Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Friend operator in template struct raises redefinition error

Consider this code:

template<typename T,typename K>
struct A{

   friend std::ostream& operator<<(std::ostream& out, K x) { 
      // Do some output 
      return out; 
   }

};

int main(){
   A<int,int> i;
   A<double,int> j;
}

It does not compile, because the two instantiations of A instantiate the operator<< two times with the same signature, so I receive this error:

test.cpp:26:25: error: redefinition of ‘std::ostream& operator<<(std::ostream&, int)’
    friend std::ostream& operator<<(std::ostream& out, K x) { return out; }
                         ^
test.cpp:26:25: error: ‘std::ostream& operator<<(std::ostream&, int)’ previously defined here

How to fix this? How can I have a friend operator in a template, when that operator might have the same signature for two different instantiations? How can I solve this without triggering a redefinition error?

like image 502
gexicide Avatar asked Aug 14 '14 11:08

gexicide


1 Answers

I don't really see any use in declaring a friend like this, nevertheless this is how you can do it:

template<typename T, typename K>
struct A{
  template<typename L>
  friend std::ostream& operator<<(std::ostream& out, L const &x);
};

template<typename T>
std::ostream& operator<<(std::ostream& out, T const &x) {
  // ... 
  return out;
}

LIVE DEMO

Edit:

Another option probably closer to what you want will be:

template<typename T>
std::ostream& operator<<(std::ostream& out, T const &x);

template<typename T, typename K>
struct A{
  friend std::ostream& operator<<<K>(std::ostream& out, K const &x);
};

template<typename T>
std::ostream& operator<<(std::ostream& out, T const &x) { 
  // ...
  return out;
}

LIVE DEMO

But really not sure why you want this. IMHO your design has serious flaws.

like image 142
101010 Avatar answered Oct 05 '22 15:10

101010