Вы не вызывающему get
от a
! Фактически, то, что получает возврат, является указателем класса на член внутри A
, и его тип int A::*
, так что вам нужен экземпляр A
для доступа к этому значению.
Например, дайте мне немного поиграть с кодом:
struct A {
A(int a):a(a) { }
int b;
private:
int a;
};
void test() {
auto p = &A::b;
std::cout << a.*p << std::endl;
}
ли я называю p
внутри a
? a
не имеет p
, это именно то, что произошло в вашем коде, get
функция возвращает &A::a
, и вы используете a
, чтобы прочитать его значение! вот и все, ничего не так, и я думаю, что он будет скомпилирован во всех компиляторах.
Еще один вопрос: почему C++ разрешает объявление шаблона с использованием частного члена A
. C++ стандарт говорит:
14.7.2p8 Обычной проверка доступ правила не применяются к именам, используемых для определения явной инстанциации. [Примечание. В частности, аргументы и имена шаблонов , используемые в деклараторе функций (включая типы параметров, типы возвращаемых данных и спецификации исключений), могут быть частных типов или объектов, которые обычно не доступны, и шаблон может быть членом шаблон или функция элемента, который бы обычно не доступен.]
Но если вы попытаетесь создать экземпляр или даже typedef
указанного шаблон, то вы получите сообщение об ошибке. Давайте немного изменить свой пример:
struct A {
private:
int a;
friend void f();
};
// Explicit instantiation - OK, no access checks
template struct Rob<A_f, &A::a>;
// Try to use the type in some way - get an error.
struct Rob<A_f, &A::a> r; // error
typedef struct Rob<A_f, &A::a> R; // error
void g(struct Rob<A_f, &A::a>); // error
// However, it's Ok inside a friend function.
void f() {
Rob<A_f, &A::a> r; // OK
typedef Rob<A_f, &A::a> R; // OK
}
Кажется странный багом, когда дело доходит до АргументЪ зависимости Lookup (ADL), я в настоящее время на моей ежевике и не могу играть с ним, - но если это компилирует должен (с моей точки зрения) рассматриваться как ошибка. –
Кто-нибудь подтвердил это, чтобы работать с любыми компиляторами, кроме gcc? – hexist
@hexist Я просто проверил это на Clang (3.1) и Intel C++ (13.0.0). –