2013-02-25 72 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