C++模板:部分模板规范和朋友类

gex*_*ide 8 c++ templates partial-specialization template-specialization friend-class

有可能以某种方式使部分模板规范成为朋友类吗?即你认为你有以下模板类

template <class T> class X{
    T t;
};
Run Code Online (Sandbox Code Playgroud)

现在你有部分特化,例如,指针

template <class T> class X<T*>{
    T* t;
};
Run Code Online (Sandbox Code Playgroud)

我想做到的是,每一个可能X<T*>是朋友类X<S>为ANY S.即X<A*>应该是的朋友X<B>.

当然,我想到了X中通常的模板朋友声明:

template <class T> class X{
    template <class S> friend class X<S*>;
}
Run Code Online (Sandbox Code Playgroud)

但是,这不能编译,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
}
Run Code Online (Sandbox Code Playgroud)

现在,编译器抱怨,当然,它x.t在构造函数中是不可见的,因为它是私有的.这就是为什么我需要一个部分专业化的朋友类.

Jir*_*ika 7

在 C++ 中,您可以授予超过private四个级别的访问权限。

  • 完全public访问(见pmr的回答)
  • 继承层次结构中的访问(protected,此处无关)
  • 到基本模板friend(请参阅此答案)
  • 到非模板或完全专业化friend(太弱而无法解决您的用例)

后两种友谊之间没有中间道路。

来自 C++ 标准的第 14.5.4 节:

友元声明不应声明部分特化。

以下声明将允许您实现所需的内容。它使您可以自由地从任何其他专业化访问模板的任何专业化,但仍仅限于X. 它比您要求的要宽松一些。

template<class T> class X
{
    template<class Any> friend class X;
    public:
        ...
};
Run Code Online (Sandbox Code Playgroud)