This announcement:
template<typename A, typename B> C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs);
... wrong because of <A,B> between operator+ and ( , I really don’t know what you would like to do here. You would use this form if you specialized in the operator+ template, but you are not here, you overload it .
This announcement should be:
template<typename A, typename B> C<A, B> operator+ (const B& lhs, const C<A, B>& rhs);
Then you must explicitly indicate in your friend declaration that you want a custom version:
friend C<A,B> operator+<>(const B& lhs, const C<A,B>& rhs);
You need to put this in front of your operator+ , otherwise the compiler will think that this specialization is not a templated function.
In any case, if you have no real reason to put code outside the C class, I would go for the @ Jarod42 solution.
All your code should look like this:
// Declaration of struct C with delayed definition template <typename A, typename B> struct C; // Initial declaration of templated operator+ template <typename A, typename B> C<A, B> operator+ (const B&, const C<A, B>&); // Definition of C template <typename A, typename B> struct C { friend C operator+<> (const B&, const C&); // This must be AFTER the templated operator+ C operator+ (const C&) const; }; template<typename A, typename B> C<A, B> C<A, B>::operator+(const C<A, B>& other) const { } template<typename A, typename B> C<A, B> operator+(const B& lhs, const C<A, B>& rhs) { }