Search code examples
c++templatesfriend

How do I make a template parameter's constructor a friend?


In C++11, they made it possible to friend a template parameter simply with friend T. You can also friend methods within that parameter with friend T::Method().

However, how do you friend a template parameter's constructor?

class BeMyFriend
{
public:
 BeMyFriend& operator=(const BeMyFriend& rhs) = default;
 BeMyFriend(const BeMyFriend& rhs) = default;
};

template<class T>
class Test
{
 friend T& T::operator=(const T&); //Works fine, no error
 friend T::T(const T&); //error: prototype for 'BeMyFriend::BeMyFriend(const BeMyFriend&)' does not match any in class 'BeMyFriend'
};

int main()
{
 Test<BeMyFriend> hmm;

 return 0;
}

I'm able to friend the template parameter's operator= just fine, but I'm unable to friend T::T(const T&).

How can I make friend T::T(const T&); work?


edit: This appears to be a different issue than what is solved in Make Friend the constructor of a template class. The issue there is dealing with circular template parameters in a declaration. It doesn't deal with the constructor of an actual template parameter.

The type of the Foo is a normal templated class, not a template parameter like T in my example. Something like friend Foo<B>::Foo<B>() from that submission should compile just fine, unlike the issue I'm having here with friend T::T(const T&).

edit: In case this ends up mattering, I'm compiling with gcc 7.2.

edit: I also want to clarify that C++ does support making constructors friends. For example, friend X::X(char), X::~X(); in the first example at http://en.cppreference.com/w/cpp/language/friend.

The issue here is how to make a template parameter's constructor a friend.


Solution

  • I was able to get it to compile in GCC by adding void after friend:

    friend void T::T(const T&);
    

    I was then able to access one of Test's private members from BeMyFriend's constructor. However, note that this is compiler specific. I tried it in clang, and it did not work.