While the solution
template <typename T>
class A
{
template<typename TT, typename U>
friend A<TT> makeA(const U & u) ;
};
works, it suffers from the side effect that makeA<int, int>
is a friend of not only A<int>
but also a friend of A<double>
, A<char>
, etc. In other workds, makeA<TT, U>
is a friend of every A<T>
. The friendship granted by A<T>
is too broad.
You can limit that by using a different design.
template <typename T> class AMaker;
template <typename T>
class A
{
A() {}
friend class AMaker<T>;
};
template<typename T> class AMaker
{
public:
template <typename U>
static A<T> make(const U & u)
{
(void) u;
return A<T>();
}
};
int main()
{
A<double> x = AMaker<double>::make(3);
return 0;
}
Here, friendship granted by A<T>
is limited to only AMaker<T>
. AMaker<int>
is friend of A<int>
but not of A<double>
.