Дружественные шаблонные функции (в нешаблонных классах), C++

Если у меня есть класс, не являющийся шаблоном (то есть «обычный»), и я хочу иметь функцию друга шаблона, как мне написать ее, не вызывая ошибки компилятора? Вот пример, иллюстрирующий то, что я пытаюсь сделать:

template <class T>
void bar(T* ptr);

class MyClass  // note that this isn't a template class
{
private:
    void foo();

    template <class T>
    friend void bar(T*);  // ERROR: compiler gives me all kinds of grief
};

template <class T>
void bar(T* ptr)
{
    if (ptr)
    {
        MyClass obj;

        obj.foo();
    }
}

Я использую Visual Studio 2005, и мне выдается конкретная ошибка: ошибка C2063, утверждающая, что "bar" не является функцией. Что здесь нужно сделать по-другому?


person Brian    schedule 19.01.2009    source источник
comment
Вы уверены? Я скопировал ваш пример кода, и он без ошибок скомпилировался в VS2005.   -  person Fabio Ceconello    schedule 19.01.2009
comment
Он также безошибочно компилируется с использованием G++ 3.4.5. Код, который вы показываете здесь, хорош. Возможно, ошибка вызвана чем-то другим?   -  person e.James    schedule 19.01.2009
comment
ваш код определенно правильный. ошибка где-то в другом месте   -  person Johannes Schaub - litb    schedule 19.01.2009
comment
Я поверю вам на слово и продолжу поиски в другом месте. Спасибо за вашу помощь!   -  person Brian    schedule 19.01.2009


Ответы (2)


Вы уверены, что то, что вы опубликовали, дает ошибку? Следующее (с использованием Visual Studio 2005) отлично работает для меня:

#include <iostream>
template <class T>
void bar(T* ptr);

class MyClass  // note that this isn't a template class
{
private:
    void foo();

    template <class T>
    friend void bar(T*);  // ERROR: compiler gives me all kinds of grief
};

void MyClass::foo()
{
    std::cout << "fooed!" << std::endl;
}

template <class T>
void bar(T* ptr)
{
    if (ptr)
    {
        MyClass obj;

        obj.foo();
    }
}


int _tmain(int argc, _TCHAR* argv[])
{

    int someObj = 1;
    bar(&someObj);

    return 0;
}
person zdan    schedule 19.01.2009

Это скорее обходной путь, чем исправление, но пытались ли вы перечислить специализации как друзей?

person mskfisher    schedule 19.01.2009
comment
Да, но поскольку есть много потенциальных специализаций, я бы хотел этого избежать. - person Brian; 19.01.2009