Я читал ответ Литба на вопрос Вот, где он подробно описывает, как создать специализированная функция друга шаблона класса.
Я попытался создать образец, который сделал только то, что он предлагает (код в конце):
// use '<>' to specialize the function template with the class template's type
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f)
Это приводит к ошибка компилятора:
error: defining explicit specialization ‘operator<< <>’ in friend declaration
Явное объявление параметра шаблона в специализации тоже не работает:
friend std::ostream& operator<< <T>(std::ostream& os, const foo<T>& f) // same error
С другой стороны, переход от специализации к использованию шаблон функции друга вместо делает Работа:
template<typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
Итак, мои вопросы:
ostream operator
для окружающего специализации шаблона класса?Пример кода ниже:
#include <iostream>
// fwd declarations
template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);
template<typename T>
struct foo
{
foo(T val)
: _val(val)
{}
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f) // error line
//template<typename U>
//friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
{
return os << "val=" << f._val;
}
T _val;
};int main()
{
foo<std::string> f("hello world");
std::cout << f << std::endl;
exit(0);
}
В примере Литба он просто объявляет специализацию своим другом в классе. Он — нет определяющий специализация, которой занимается ваш код. Вам не разрешено определять специализацию в объявлении класса (или в любой области без пространства имен).
Что вам нужно, это что-то вроде:
template <class T>
class foo;
template<class T>
std::ostream& operator<<(std::ostream& os, const foo<T>& f)
{
return os << "val=" << f._val;
}
template<typename T>
struct foo
{
// ...
private:
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);
T _val;
};
У вас есть 2 варианта:
Удалите объявления fwd и определите все в классе.
пример
template <typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
{
return os << "val=" << f._val;
}
Определите функцию друга вне класса.
пример
template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);
template<typename T>
struct foo
{
foo(T val)
: _val(val)
{}
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);
T _val;
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const foo<T>& f)
{
return os << "val=" << f._val;
}