Class template member function

I am trying to get a friend function inside a template to compile, but I do not understand the error message and warning. I made a demonstration of the problem. The error I get is:

prog.cpp: 8: 57: error: non-classical, non-variable partial specialization C + operator (const B & lhs, const C & rhs);

prog.cpp: 15: 59: warning: friend declaration “operator C + (const B &, const C &)” declares a function without the template [-Wnon-template-friend] friend of the C operator + (const B & lhs, const C & rhs);

prog.cpp: 15: 59: note: (if this is not what you intended, make sure the function template is already declared and add <> after the function name here)

#include <iostream> using namespace std; template<typename A, typename B> class C; template<typename A, typename B> C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs); template<typename A, typename B> struct C { A val_; C operator+(const C& other) const; friend C<A, B> operator+(const B& lhs, const C<A, B>& rhs); }; template<typename A, typename B> C<A, B> C<A, B>::operator+(const C<A, B>& other) const { C<A, B> c; c.val_ = this->val_ + other.val_; return c; } template<typename A, typename B> C<A, B> operator+(const B& lhs, const C<A, B>& rhs) { C<A, B> c; c.val_ = lhs + rhs.val_; return c; } int main() { C<string, char> c0,c1; c0.val_ = " C0 "; c1.val_ = " C1 "; cout << "Stuct:" << (c0 + c1).val_ << '\n'; cout << "Friend:" << ('~' + c1).val_ << endl; return 0; } 
+8
c ++ c ++ 11 friend templates
source share
2 answers

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) { } 
+3
source share

The simplest is the inline code inside the class:

 template <typename A, typename B> struct C { A val_; C operator+(const C& other) const { C c; c.val_ = this->val_ + other.val_; return c; } friend C operator+ (const B& lhs, const C& rhs) { C c; c.val_ = lhs + rhs.val_; return c; } }; 

Demo

The code is not embedded in the class, which requires a lot of attention as a direct declaration of the declaration order, strange syntax <> :

 template <typename A, typename B> struct C; template <typename A, typename B> C<A, B> operator+ (const B& lhs, const C<A, B>& rhs); template <typename A, typename B> struct C { A val_; friend C<A, B> operator+<> (const B& lhs, const C<A, B>& rhs); C operator+(const C& other) const; }; template <typename A, typename B> C<A, B> operator+ (const B& lhs, const C<A, B>& rhs) { C<A, B> c; c.val_ = lhs + rhs.val_; return c; } template <typename A, typename B> C<A, B> C::operator+(const C<A, B>& other) const { C<A, B> c; c.val_ = this->val_ + other.val_; return c; } 

Demo

+5
source share

All Articles