Может ли указатель на члены обойти уровень доступа члена?

В нашем печально известном litb есть интересная статья о том, как обойти проверку доступа.

Это полностью демонстрируется этим простым кодом:

#include 

template
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;

int main() {
  A a(42);
  std::cout << "proof: " << a.*get(A_f()) << std::endl;
}

Который компилируется и запускается (выход 42) с gcc 4.3.4, gcc 4.5.1, gcc 4.7.0 (см. комментарий пользователя 1131467) и компилируется с помощью Clang 3.0 и Comeau C/C++ 4.3.10.1 в строгом режиме C++03и MSVC 2005.

Лучиан спросил меня о этот ответ, в котором я использовал его, чтобы обосновать, что это действительно законно. Я согласен с Лучианом в том, что это странно, однако и Clang, и Comeau являются близкими претендентами на звание наиболее "стандартных" доступных компиляторов (намного больше, чем MSVC по умолчанию)...

И я не смог ничего найти в черновиках стандарты, которые у меня есть (n3337 - последняя версия, которую я получил).

Итак... кто-нибудь может на самом деле обосновать, что это законно или нет?

13
задан Community 23 May 2017 в 12:11
поделиться