Mi scuso se il titolo di questa domanda è meno che utile; Io non conosco un modo succinto di fare questa domanda senza dare l'esempio seguente:Un argomento modello template da un altro spazio dei nomi può essere un amico?
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_;
};
}
Come si può vedere, Arg2
è una copia di Arg1
. Tuttavia, VS 2008 consente solo Arg1
per essere usato come un argomento di un template:
int main() {
C<Arg1> c1; // compiles ok
C<NS::Arg2> c2; // error C2248
return 0;
}
L'errore è 'C<Arg>::i_' : cannot access private member declared in class 'C<Arg>'
. Tutto funziona bene se i_
è reso pubblico, quindi questo sembra essere un problema di amicizia.
Che cosa causa la mancata riuscita della dichiarazione di amicizia quando l'argomento del modello di modello si trova in uno spazio dei nomi diverso?
Dovrei aggiungere che lo stesso codice non riesce a compilare sia in VS 2010 che in VS 2012. –