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

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

template <class T> class X{
    T t;
};

现在你有部分专业化,例如,针对指针

template <class T> class X<T*>{
    T* t;
};

我想完成的是每个可能的X<T*>都是X<S>的朋友类,适用于任何SX<A*> <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
}

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


在C ++中,您可以授予访问权限以外private四个层次。

  • 完全public访问(见pmr的答案)
  • 在继承层次结构中访问( protected ,在这里不相关)
  • 到基本模板的friend (请参阅此答案)
  • 到非模板或完全专业化的friend (太弱以至于无法解决您的使用案例)
  • 后两种友谊之间没有中间路线。

    从C ++标准的§14.5.4开始:

    朋友声明不得声明部分专业。

    下面的声明将允许你实现你所需要的。 它可以让你自由地从任何其他专业化的角度访问你的模板的任何专长,但仍然只在X范围内。 它比你所要求的稍宽一些。

    template<class T> class X
    {
        template<class Any> friend class X;
        public:
            ...
    };
    

    我们可以定义一个由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 。 但是现在这样混淆了,没有人会意识到这一点。 我会选择一个简单的公共获得者。

    链接地址: http://www.djcxy.com/p/60595.html

    上一篇: C++ Templates: Partial Template Specifications and Friend Classes

    下一篇: How can I get the public key of a webpage?