Почему это законно для ненадлежащего доступа к частным лицам в явном экземпляре?

Почему бы это не было позволено:

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
template<typename T>
struct invisible
{
    static typename T::type value;
};

template<typename T>
typename T::type invisible<T>::value;

//////////////////////////////////////////////////////////////////////////
template<typename T, typename T::type P>
class construct_invisible
{
    construct_invisible(){ invisible<T>::value = P; }
    static const construct_invisible instance;
};

template<typename T, typename T::type P>
const construct_invisible<T, P> construct_invisible<T, P>::instance;

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class A
{
public:
    A(int x) : m_X(x){}
private:
    int m_X;
};

//////////////////////////////////////////////////////////////////////////
struct A_x{ typedef int A::*type; };
template class construct_invisible<A_x, &A::m_X>;// <---- WHY DOES `&A::m_X` WORK HERE?

//////////////////////////////////////////////////////////////////////////
int main()
{
    A a(17);
    std::cout << a.*invisible<A_x>::value << '\n';
}

Кредит переходит на Йоханнес Шауб за вышеуказанное злоупотребление C++. (Демо)

Существуют ли другие случаи, когда вы можете получить доступ к тому, что должно быть невидимым для вас? Это просто "ошибка" в стандарте?

Ответ 1

Это так, что автор класса, который имеет частный член, может явно создать экземпляр этого элемента или передать его как аргумент, который вы только что сделали.

Компилятор не знает, кто стоит перед клавиатурой, поэтому проверка доступа здесь довольно консервативна.

Параметры, используемые в явном экземпляре, получают специальное обращение, потому что для автора класса нет механизма для явного экземпляра шаблона в разрешенном контексте или каким-то образом разрешить это делать с объявлением друга.