2013-02-25 59 views
5

如果这个问题的标题不够有帮助,我表示歉意。我不知道一个简洁的方式来问这个问题不给下面的例子:不同名称空间的模板模板参数可以成为朋友吗?

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<Arg>::i_' : cannot access private member declared in class 'C<Arg>'。如果i_是公开的,一切正常,所以这似乎是一个友谊问题。

是什么原因造成的友谊声明时模板的模板参数是不同的命名空间失败?

+0

我要补充的是,同样的代码也无法在这两个VS 2010和VS 2012 – 2013-02-26 04:49:29

回答

0

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

friendnamespace是语言功能的互动,虽然如此,它并不特别令人惊讶,因为臭虫去。也许它实际上是在封闭的命名空间::Arg2<type>中加入无意义的前向声明。

+0

编译鉴于其他(现已删除)的意见表明铛和gcc编译我的例子中没有错误,我想这是正确的回答。 – 2013-02-26 04:58:11