akim
akim

Reputation: 8759

Friend member function definition in class templates

The following piece of code fails to compile properly with both G++ and Clang++, whatever the C++ standard required (98, 11, 14):

$ cat foo.cc
template <typename T>
struct foo
{
  friend void bar(){}
};

int main()
{
  foo<int> fi;
  foo<char> fc;
}

for instance:

$ clang++-mp-3.7 -std=c++14 foo.cc
foo.cc:4:15: error: redefinition of 'bar'
  friend void bar(){}
              ^
foo.cc:10:13: note: in instantiation of template class 'foo<char>' requested here
  foo<char> fc;
            ^
foo.cc:4:15: note: previous definition is here
  friend void bar(){}
              ^
1 error generated.

I know I can avoid this problem by putting the definition (not declaration) of bar out of foo, I'm not asking for a workaround. Rather, I would like to understand what's going on. So I have two questions:

Upvotes: 3

Views: 222

Answers (1)

Simon Kraemer
Simon Kraemer

Reputation: 5680

For each T a new class is created. So foo<int> is one class and foo<char> is another.

If you take your example and unwind it, it will look like this:

struct foo_int
{
    friend void bar() {}
};

struct foo_char
{
    friend void bar() {}
};


int main()
{
    foo_int fi;
    foo_char fc;
}

Through the friend keyword you are defining a static global (namespace scope) function named bar. And as you see here you are doing it twice.

Upvotes: 3

Related Questions