Other answers suggest using a static template function, which I agree is the best solution because it is simpler.
My answer explains why your friend wasn’t working and how to properly use the friends approach.
There are two problems in the source code. One of them is that make_unique is not really a friend of A , so calling make_unique<A<T>>(myarg); does not have access to A protected constructor. To avoid this, you can use unique_ptr<A<T>>(new A(myarg)) instead. Theoretically, one could declare a make_unique friend, but I'm not even sure of the correct syntax for this.
Another problem is the problem with friends in templates . Inside the class template, friend <function-declaration> actually declares a friend without templates.
C ++ FAQs offer two possible solutions. One of them is to define a friend function inline. However, in this case, the function can only be found using an argument-dependent search. But since the function does not accept A<T> (or A<T> & ) as an argument, it can never be found this way. Thus, this option is not suitable for your situation - it is more suitable for operator overload.
So the only fix is to declare (and optionally define) the template function before defining the class:
#include <memory> template<typename T> class A; template <typename T> std::unique_ptr<A<T>> CreateA(int myarg) { return std::unique_ptr<A<T>>{new A<T>(myarg)}; } template <typename T> class A { friend std::unique_ptr<A<T>> CreateA <> (int myarg); // refers to existing template ^^ protected: A(int myarg) {} }; int main() { auto x = CreateA<int>(5); }
Note. You can declare CreateA , where I defined it, and put the function definition later. However, the code I posted works even though A not detected when new A<T>(myarg) appears in the source, because CreateA not created before it is called, after which A will be defined.
MM
source share