[英]How to make template function friend of template class
我有一个带有私有构造函数和析构函数的模板类:
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>(...);
}
我不确定朋友的语法正确。 有人可以帮忙吗?
忽略省略号(我假设它的意思是“与问题无关的一堆参数”),这应该可以工作:
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()
{
/* ... */
}
请注意,friend声明与函数声明本质上相同,但是在返回类型之前加有friend
关键字前缀。
而且,析构函数是公共的,因此initialize()
用户将能够破坏所返回的Client<>
实例。 构造函数仍然是私有的,因此只有initialize()
可以创建它的实例。
上面的代码应允许它工作:
int main()
{
Client<int> client = initialize<int>();
}
template <typename U> friend Client<U> initialize(.....);
这取决于您要实现的目标。 您可能希望与模板的一个实例化成为朋友,或者与所有实例化成为朋友。 最后,您可能真的不想成为模板的朋友,而只是一个非模板函数,该函数是在实例化类模板时由编译器自动生成的...
与整个模板成为朋友:
template <typename T>
class MyClass {
template <typename U>
friend MyClass<U> f();
};
结识具体的实例化(例如,允许f<int>
访问MyClass<int>
但不允许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() { ... }
友善的非模板功能的自动实例化:
template <typename T>
class MyClass {
friend MyClass<T> f() { ... } // define inline
};
我建议您使用后者,除非该函数使用MyClass<T>
的T
以外的其他模板参数进行参数化。
您可能应该将销毁者public
。 如果需要将其保持private
,则需要声明另一个friend
函数来删除已创建的Client
对象。
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.