Явная специализация функции друга для шаблона класса

Я читал ответ Литба на вопрос Вот, где он подробно описывает, как создать специализированная функция друга шаблона класса.

Я попытался создать образец, который сделал только то, что он предлагает (код в конце):

// 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);
}

4

Решение

В примере Литба он просто объявляет специализацию своим другом в классе. Он — нет определяющий специализация, которой занимается ваш код. Вам не разрешено определять специализацию в объявлении класса (или в любой области без пространства имен).

Что вам нужно, это что-то вроде:

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;
};
3

Другие решения

У вас есть 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;
}
2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector