代码之家  ›  专栏  ›  技术社区  ›  David

为什么在显式实例化中不适当地访问私有信息是合法的?

  •  11
  • David  · 技术社区  · 13 年前

    究竟为什么会允许这样做:

    //////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////
    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';
    }
    

    信用卡转到 Johannes Schaub 针对上述C++滥用。( Demo )

    是否还有其他情况下,您可以访问对您来说不可见的内容?这只是标准中的一个“bug”吗?

    1 回复  |  直到 13 年前
        1
  •  4
  •   Praxeolitic    11 年前

    这样,拥有私有成员的类的作者就可以显式地实例化该成员,或者像您刚才所做的那样将其作为参数传递。

    编译器不知道谁在键盘前面,所以这里的访问检查相当保守。

    显式实例化中使用的参数得到了特殊处理,因为类作者没有机制在允许的上下文中显式实例化模板,或者以某种方式允许使用友元声明来这样做。