Il nostro famigerato litb ha un interessante articolo su how to circumvent the access check.Il puntatore ai membri elude il livello di accesso di un membro?
E 'pienamente dimostrato da questo semplice codice:
#include <iostream>
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// use
struct A {
A(int a):a(a) { }
private:
int a;
};
// tag used to access A::a
struct A_f {
typedef int A::*type;
friend type get(A_f);
};
template struct Rob<A_f, &A::a>;
int main() {
A a(42);
std::cout << "proof: " << a.*get(A_f()) << std::endl;
}
che riunisce e piste (in uscita) con 42
gcc 4.3.4, gcc 4.5.1, gcc 4.7.0 (vedi il commento di user1131467) e compila con Clang 3.0 e Comeau C/C++ 4.3.10.1 in C++ 03 rigorosa modalità e MSVC 2005.
mi è stato chiesto da Luchian su this answer in cui ho usato per giustificare il fatto che in realtà era legale. Sono d'accordo con Luchian che è strano, tuttavia sia Clang che Comeau sono contendenti per i compilatori più "Standard" disponibili (molto più di MSVC di default) ...
E non ho trovato nulla nelle bozze degli standard che ho a disposizione (n3337 è l'ultima versione su cui ho messo le mani).
Quindi ... qualcuno può effettivamente giustificare che sia legale o non?
FYI Questo produce 'proof: 42' con' g ++ - 4.7 (Debian 4.7.0-1) 4.7.0' in entrambi '-std = C++ 11' e' -std = gnu ++ 11' –
Scusa, questo è il mio cattivo. Questo è compilato, ciò che non è stato compilato era http://stackoverflow.com/a/6886432/673730 - e stavo cercando di accedere a una funzione privata, non a un membro dei dati. –
Comunque sto ancora cercando una risposta, se la risposta ha funzionato, sarebbe stato esattamente quello che stavo cercando, ma non è così. –