2010-01-16 5 views
2

Мой вопрос связан немного с this один.функция друга в определении шаблона

Я хочу, чтобы перегрузить оператор < < для некоторого класса, и я нашел две разные обозначения, что и работа:

template <class T> 
class A{ 
    T t; 
public: 
    A(T init) : t(init){} 
    friend ostream& operator<< <> (ostream &os, const A<T> &a); //need forward declaration 
    //template <class U> friend ostream& operator<< (ostream &os, const A<U> &a); 
}; 

ли я определить одинаковые вещи с разными обозначениями? Или первая версия более ограничительная, в каком экземпляре (в данном случае только экземпляр с тем же T, что и мой класс A) < < является другом A?

ответ

1

Первая версия ограничивает дружбу к operator<< для конкретного типа A<T>, в то время как второй делает любой operator<<, который принимает A<SomeType> друга.

Так да, первый из них является более ограничительным:

template<class T> 
ostream& operator<< (ostream& os, const A<T>& a) { 
    A<double> b(0.0); 
    b.t; // compile error with version 1, fine with version 2 
    return os; 
} 

int main() { 
    A<int> a(0); 
    cout << a << endl; 
} 
+0

Пара вещей. Во-первых, я думаю, вы имели в виду «os << b.t», а не «os << b.i» для вывода принадлежащей члену переменной. Во-вторых, приведенный выше пример будет отлично работать с любым оператором << instance, поскольку он будет использовать функцию ostreame & operator << (ostream & os, double num) ', а не объявленную версию шаблона. – workmad3

+0

У меня была голова где-то в другом месте, но это было исправлено в среднем. –

0

Так получилось, что определение другу функций есть исключение для шаблонов. Это позволяет писать так:

template <class T> 
class A{ 
    T t; 
public: 
    A(T init) : t(init){} 
    friend ostream& operator<<(ostream &os, const A &a) 
    { // Implementation in the class 
    } 
}; 

И он имеет преимущество создания нормальной функции автоматически создается для каждого экземпляра A<T> вы создаете.

Справочно: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16

+0

с «исключением» вы имеете в виду, что вам не нужно писать A в определении оператора? Мой вопрос: действительно ли это преимущество? Хорошо, у вас нет версии шаблона <<, но в приведенных выше случаях также создан экземпляр шаблона для <<, если он используется где-то с определенным классом. – haselhorstk

+0

Главным преимуществом было бы то, что вам не нужны форвардные объявления ... вы должны всегда определять его в каждом классе, хотя. –

+0

Настоящим преимуществом является то, что вы не определяете шаблон функции вообще! Таким образом, у вас нет какой-либо связанной проблемы, например, с принуждением. – PierreBdR