Explicit specialization of friend function for a class template
c++, templates
Solution
In litb's example, he's just declaring the specialization as a friend in the class. He's not defining the specialization, which is what your code's doing. You're not allowed to define a specialization in a class declaration (or any non-namespace scope).
What you need is something like:
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;
};
Problem
I was reading litb's answer to a question here, where he details how to create a specialized friend function of a class template. I tried to create an exemplar which did just what he suggests (code at the end): ``` // use '<>' to specialize the function template with the class template's type friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f) ``` It results in a compiler error: ``` error: defining explicit specialization ‘operator<< <>’ in friend declaration ``` Explicitly declaring the template parameter in the specialization doesn't work either: ``` friend std::ostream& operator<< <T>(std::ostream& os, const foo<T>& f) // same error ``` On the other hand, changing from using a specialization to use a friend function template instead does work: ``` template<typename U> friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works ``` So my questions are: - what is causing the first error? - how can I explicitly specialize the `ostream operator` for the surrounding class template specialization? Exemplar code below: ``` #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); } ```