2013-02-25 2 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에서 모두 컴파일되지 않는다고 덧붙여 야합니다. –

답변

0

네임 스페이스 멤버십은 우정 적격 여부에 영향을주지 않습니다. 이것은 컴파일러 버그입니다.

friendnamespace은 상호 작용하는 언어 기능이므로 버그가 발생하는 것처럼 특히 놀라운 것은 아닙니다. 실제로 그것은 둘러싸는 네임 스페이스의 말도 안되는 선언을 실제로 friending하고있다, ::Arg2<type>.

+0

clang과 gcc가 오류없이 예제를 컴파일한다는 것을 나타내는 다른 주석 (이제 삭제됨)이 주어지면, 이것이 올바른 것 같습니다. 대답. –

관련 문제