I have a template class with private constructor and destructor:
template <typename T>
class Client
{
private:
Client(...) {}
~Client() {}
template <typename U>
friend class Client<T>& initialize(...);
};
template <typename T>
Client<T> initialize(...)
{
Client<T> client = new Client<T>(...);
}
I'm not sure of the correct syntax for the friend. Can anybody help?
Ignoring the ellipses (which I assume mean "a bunch of parameters that aren't relevant to the question"), this should work:
template <typename T>
class Client
{
private:
Client() {} // Note private constructor
public:
~Client() {} // Note public destructor
// Note friend template function syntax
template<typename U>
friend Client<U> initialize();
};
template<typename T>
Client<T> initialize()
{
/* ... */
}
Notice that the friend declaration is essentially the same as the function declaration but with the friend
keyword prefixed before the return type.
Also, the destructor is public so that users of initialize()
will be able to destruct the returned instance of Client<>
. The constructor is still private so only initialize()
can create instances of it.
The above code should allow this to work:
int main()
{
Client<int> client = initialize<int>();
}
template <typename U> friend Client<U> initialize(.....);
It depends on what exactly you are trying to achieve. You may want to befriend a single instantiation of the template, or you might want to befriend all instantiations. Finally you might not really want to befriend a template, but just a non-templated function that is automatically generated by the compiler upon instantiation of your class template...
Befriending the whole template:
template <typename T>
class MyClass {
template <typename U>
friend MyClass<U> f();
};
Befriending a concrete instantiation (i.e. allowing f<int>
access to MyClass<int>
but not to MyClass<double>
):
// Forward declarations
template <typename T>
class MyClass;
template <typename T>
MyClass<T> f();
// Definition of class template
template <typename T>
class MyClass {
friend MyClass<T> f<T>();
};
// Definition of friend function
template <typename T>
MyClass<T> f() { ... }
Automatic instantiation of a befriended non-template function:
template <typename T>
class MyClass {
friend MyClass<T> f() { ... } // define inline
};
I would recommend that you use the latter, unless the function is parametrized with other template parameters than the T
for MyClass<T>
.
Recommend reading: overloading friend operator<< for template class
You should probably make your destructor public
. If you need to keep it private
you need to declare another friend
function to delete the Client
objects that you've created.
template <typename T>
class Client
{
private:
Client() {}
~Client() {}
template <typename U>
friend Client<U> *initialize();
template <typename U>
friend void destroy( Client<U> * );
};
template <typename T>
Client<T> *initialize()
{
return new Client<T>();
}
template <typename T>
void destroy( Client<T> *client )
{
delete client;
}
int main()
{
auto client = initialize<int>();
destroy( client );
return 0;
}