【问题标题】:Can a template template argument from different namespace be a friend?来自不同命名空间的模板模板参数可以成为朋友吗?
【发布时间】:2013-02-25 22:02:41
【问题描述】:

如果这个问题的标题没有帮助,我深表歉意;如果不给出以下示例,我不知道如何简洁地提出这个问题:

template <template <class> class Arg>
class C {
    typedef C<Arg> type;
    friend class Arg<type>;
  public:
    C() {
        a_.set(this);
    }
  private:
    int i_;
    Arg<type> a_;
};

template <class Type>
class Arg1 {
  public:
    void set(Type* t) {
        t_ = t;
        t_->i_ = 1;
    }
  private:
    Type* t_;
};

namespace NS {

    template <class Type>
    class Arg2 {
      public:
        void set(Type* t) {
            t_ = t;
            t_->i_ = 2;
        }
      private:
        Type* t_;
    };

}

如您所见,Arg2Arg1 的副本。但是,VS 2008 只允许 Arg1 用作模板参数:

int main() {
    C<Arg1> c1; // compiles ok
    C<NS::Arg2> c2; // error C2248

    return 0;
}

错误是'C&lt;Arg&gt;::i_' : cannot access private member declared in class 'C&lt;Arg&gt;'。如果i_ 公开,一切正常,所以这似乎是一个友谊问题。

当模板模板参数位于不同的命名空间时,导致友谊声明失败的原因是什么?

【问题讨论】:

  • 我应该补充一点,相同的代码在 VS 2010 和 VS 2012 中也无法编译。

标签: c++ templates template-templates


【解决方案1】:

命名空间成员资格不影响友谊的资格。这是一个编译器错误。

friendnamespace 是可以交互的语言特性,因此出现 bug 也就不足为奇了。也许它实际上是在封闭命名空间::Arg2&lt;type&gt; 中添加一个无意义的前向声明。

【讨论】:

  • 鉴于其他(现已删除)cmets 表明 clang 和 gcc 编译我的示例没有错误,我认为这是正确的答案。
猜你喜欢
  • 2018-10-20
  • 2017-08-08
  • 1970-01-01
  • 2010-10-16
  • 2018-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多