2009-10-21 14 views
9

Mam problem, że jeśli mam klasę szablonu, która z kolei ma metodę szablonu, która pobiera parametr innej instancji klasy (z różnymi argumentami szablonu), to nie może dostęp chroniony lub prywatnych członkowie klasy przekazany jako parametr, np:C++ Problem z dostępem członków klasy z szablonami

template<typename T>class MyClass 
{ 
    T v; 
public: 
    MyClass(T v):v(v){} 

    template<typename T2>void foo(MyClass<T2> obj) 
    { 
     std::cout << v  << " "; 
     //error C2248: 'MyClass<T>::v' : cannot access private member declared in class 'MyClass<T>' 
     std::cout << obj.v << " "; 
     std::cout << v + obj.v << std::endl; 
    } 
}; 
int main() 
{ 
    MyClass<int> x(5); 
    MyClass<double> y(12.3); 
    x.foo(y); 
} 

Czy istnieje jakiś sposób, aby powiedzieć, że metody MojaKlasa <T> mieć pełny dostęp do MojaKlasa <SomeOtherT>?

Odpowiedz

9

Są to różne typy: szablony tworzą nowe typy z szablonu.

Trzeba wprowadzić inne dawałaby swoich przyjaciół Klasa:

template <typename T>class MyClass 
{ 
    T v; 
public: 
    MyClass(T v):v(v){} 

    template<typename T2>void foo(MyClass<T2> obj) 
    { 
     std::cout << v  << " "; 
     std::cout << obj.v << " "; 
     std::cout << v + obj.v << std::endl; 
    } 

    // Any other type of MyClass is a friend. 
    template <typename U> 
    friend class MyClass; 

    // You can also specialize the above: 
    friend class MyClass<int>; // only if this is a MyClass<int> will the 
           // other class let us access its privates 
           // (that is, when you try to access v in another 
           // object, only if you are a MyClass<int> will 
           // this friend apply) 
}; 
+0

Glee! : D [15char] – GManNickG

+0

Twój kod właściwie nie kompiluje się w Comeau i nie mogę znaleźć sposobu, w jaki pozwala na to Standard. Wierzę, że 'szablon' przed' przyjacielem' jest konieczny z powodu 14.5.3/3. –

+0

Właściwie to też miałem :(usunąłem go, ponieważ uważałem, że to niepotrzebne. (Po testowaniu w VS) nie powinienem tego testować ... Dodam go ponownie. Bah! – GManNickG

7

Dodaj MyClass znajomego Klasa:

template<typename T> class MyClass 
{ 
    template<typename TX> 
    friend class MyClass; 
... 

Według standardu C++ 14.5.3/3:

Szablon znajomego może zostać zadeklarowany w szablonie klasy lub klasy. Szablon funkcji znajomego może być zdefiniowany w szablonie klasy lub klasy, ale szablon klasy przyjaciela może nie zostać zdefiniowany w szablonie klasy lub klasy. W takich przypadkach wszystkie specjalizacje szablonu przyjaciela lub przyjaciela są zaprzyjaźnione z szablonem klasy lub klasy zapewniającym przyjaźń. [Przykład:

class A { 
    template<class T> friend class B; // OK 
    template<class T> friend void f(T){ /* ... */ } // OK 
}; 

końcem przykład]

UWAGA: Należy pamiętać, że powyższy kod nadal może prowadzić do błędów w niektórych kompilatorów powodu Core Issue #602 który jest nadal otwarta. Mimo to powyższy kod kompiluje GCC, Visual C++ i Comeau.

Aby jedyną funkcją foo znajomemu można napisać następujące:

template<typename T> class MyClass 
{ 
    template<typename TY> template<typename TX> 
    friend void MyClass<TY>::foo(MyClass<TX>); 
... 
+0

Tak, ten kod sprawia MojaKlasa przyjacielem MojaKlasa dla wszystkich TX. Czy to możliwe, aby tylko MyClass :: foo znajomego zamiast całej klasy? – user200783

+0

@Paul, mam zaktualizowane odpowiedź. –

Powiązane problemy