是否有可能以某种方式使部分模板规范成为朋友类?即考虑您有以下模板类
template <class T> class X{
T t;
};
现在你有部分专业化,例如指针
template <class T> class X<T*>{
T* t;
};
我想要完成的是,每个可能的X<T*>
都是X<S>
的朋友类,适用于任何S
。即X<A*>
应该是X<B>
的朋友。
当然,我想到了X中常见的模板好友声明:
template <class T> class X{
template <class S> friend class X<S*>;
}
但是,这不能编译,g ++告诉我这个:
test4.cpp:34:15:错误:'template<class T> class X
'的特化必须出现在命名空间范围
test4.cpp:34:21:错误:部分特化“X<S*>
”声明为“朋友”
这根本不可能,还是有一些解决方法?
我之所以要问的是,我需要X<T*>
中的构造函数从任意X<S>
创建此类(S
必须是T
的子类型)
代码如下所示:
template <class T> class X<T*>{
T* t;
template<class S>
X(X<S> x) : t(&(x.t)) {} //Error, x.t is private
}
现在,编译器抱怨,x.t
在构造函数中是不可见的,因为它是私有的。这就是为什么我需要一个部分专业化的朋友类。
答案 0 :(得分:3)
在C ++中,您可以在四个级别上授予private
以外的访问权限。
public
访问权限(请参阅pmr的回答)protected
内访问,此处无关紧要)friend
(请参阅此答案)friend
(太弱而无法解决您的使用案例)后两种友谊之间没有中间道路。
来自C ++标准的§14.5.4:。
朋友声明不得声明部分专业化。
以下声明将允许您实现所需。它让您可以自由地从任何其他专业化访问模板的任何专业化,但仍然只能在X
内。它比你要求的更宽松。
template<class T> class X
{
template<class Any> friend class X;
public:
...
};
答案 1 :(得分:1)
我们可以定义受X中定义的密钥保护的getter
。
#include <type_traits>
template <class T> class X{
T t;
public:
struct Key {
template<typename S>
Key(const X<S>&) {
static_assert(std::is_pointer<S>::value, "Not a pointer");
}
};
const T& get(Key) const { return t; }
T& get(Key) { return t; }
};
template <class T> class X<T*> {
T* t;
public:
template<class S>
X(X<S>& x) : t(&(x.get(typename X<S>::Key(*this)))) {}
};
int main()
{
X<int> x1;
X<int*> x2(x1);
return 0;
}
这仍有一些弱点。拥有X<T*>
的每个人现在都可以使用
get
。但是现在这种情况很混乱,没有人会这么做
认识到。我会选择一个简单的公共吸气剂。