friend and templates
От: Аноним  
Дата: 17.03.06 19:41
Оценка:
Доброго времени суток. Подскажите плз как сделать чтобы дружественная функция могла принимать/возвращать в качестве аргумента объект параметризованого класса?

e.g.

template <class T> class A
{
private:
    
    T a;
    T b;
    
public:

    A();
    A(T aa, T bb);
    
    friend std::ostream& operator<< (std::ostream& os, A<T>& t);
};

template <class T> std::ostream& operator<< (std::ostream& os, A<T>& t)
{
    os << t.a << std::endl << t.b;
    return os;
}


При линковке выдается сообщение об ошибке:

gcc 3.4.2:
undefined reference to `operator+(int, A<int>&)'

VC2003:
unresolved external symbol "int __cdecl operator+(int,class A<int> &)"


Если же реализовать фукцию operator<< сразу же в теле класса, то ни каких проблем. В чем моя ошибка?

Заранее благодарен.

Раскраска синтаксиса: тэг [ccode] вместо [code] — Кодт
Re: friend and templates
От: st.  
Дата: 17.03.06 19:46
Оценка:
Предыдущее сообщение написал я — забыл войти под своим ником
В ошибке выдается конечно не "operator+" а "operator<<".
Re: friend and templates
От: shank  
Дата: 17.03.06 20:09
Оценка:
Здравствуйте, Аноним, Вы писали:

Так пашет.
#include <iostream>

template<class T>
class A;

template <class T>
std::ostream& operator<< (std::ostream& os, const A<T>& t);

template <class T> class A
{
private:

    T a;
    T b;

public:

    A();
    A(T aa, T bb):a(aa), b(bb){}

    friend std::ostream& operator<< <> (std::ostream& os, const A<T>& t);
};

template <class T> std::ostream& operator<< (std::ostream& os, const A<T>& t)
{
    os << t.a << std::endl << t.b;
    return os;
}

int main()
{
    A<int> a(11, 22);
    std::cout << a;
}
Re[2]: friend and templates
От: st.  
Дата: 17.03.06 20:38
Оценка:
а пояснить можно?
Re[3]: friend and templates
От: shank  
Дата: 17.03.06 20:53
Оценка:
Здравствуйте, st., Вы писали:

st.>а пояснить можно?


Шаблонная friend-функция должна быть предварительно объявлена вне класса.
Чтобы компилятор знал что operator<< является шаблоном, надо добавить угловые скобки <>,
параметр T указывать необязательно, т.к. он выводится автоматически.
Подробнее Джосаттис, Вандевурд "Шаблоны С++" глава 8.4.
Re: friend and templates
От: saddva  
Дата: 17.03.06 21:02
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Доброго времени суток. Подскажите плз как сделать чтобы дружественная функция могла принимать/возвращать в качестве аргумента объект параметризованого класса?


А>e.g.


А>
А>template <class T> class A
А>{
А>private:
    
А>    T a;
А>    T b;
    
А>public:

А>    A();
А>    A(T aa, T bb);
    
А>    friend std::ostream& operator<< (std::ostream& os, A<T>& t);
А>};

А>template <class T> std::ostream& operator<< (std::ostream& os, A<T>& t)
А>{
А>    os << t.a << std::endl << t.b;
А>    return os;
А>}
А>


А>При линковке выдается сообщение об ошибке:


А>gcc 3.4.2:

А>undefined reference to `operator+(int, A<int>&)'

А>VC2003:

А>unresolved external symbol "int __cdecl operator+(int,class A<int> &)"


А>Если же реализовать фукцию operator<< сразу же в теле класса, то ни каких проблем. В чем моя ошибка?


А>Заранее благодарен.


В теле шаблона класса A есть объявление
friend std::ostream& operator<< (std::ostream& os, A<T>& t);

А далее в коде есть определение какзалось бы того же оператора, но на самом деле компилятор (я надеюсь, у Вас не 6-я студия) воспринимает их как разные вещи, пока Вы явно не укажете, что в теле класса другом объявляется шаблон-оператор:
template <class U>
friend std::ostream& operator<< (std::ostream& os, A<U>& t);

Но лучше объявить шаблон-оператор "<<" заранее (до определения шаблона класса A):
template <class T>
std::ostream& operator<< (std::ostream& os, A<T>& t);

И в теле класса сделать дружественным только тот оператор вывода, который будет построен из шаблона с тем же параметром, что и используемый в шаблоне класса, т.е.:
friend std::ostream& operator<< <T>(std::ostream& os, A<T>& t);

или короче:
friend std::ostream& operator<< <>(std::ostream& os, A<T>& t);
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.