11

いったいなぜこれが許されるのでしょうか。

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
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++の乱用については、JohannesSchaubにクレジットが与えられます。(デモ

あなたがあなたに見えないはずのものにアクセスできる他のケースはありますか?これは標準の単なる「バグ」ですか?

4

1 に答える 1

4

これは、プライベートメンバーを持つクラスの作成者が、そのメンバーを明示的にインスタンス化するか、または今行ったように引数として渡すことができるようにするためです。

コンパイラは誰がキーボードの前にいるのかわからないので、ここでのアクセスチェックはかなり保守的です。

明示的なインスタンス化で使用されるパラメーターは、クラス作成者が許可されたコンテキストでテンプレートを明示的にインスタンス化するメカニズムや、フレンド宣言を使用してそれを許可するメカニズムがないため、特別な扱いを受けます。

于 2012-08-21T07:37:46.773 に答える