c++ - 为什么此代码允许访问私有(private)变量

标签 c++ templates private

几天前我遇到了这种方法(作为 C++ course 中编程任务的解决方案之一)。

#include <iostream>

struct C {
    C(int i) { m_i = i; }
private:
    int m_i;
};

template<typename Tag, int C::* M>
struct Rob {
    friend
    int C::* get(Tag) {
        return M;
    }
};

template<typename D>
struct AcessorTag {
    typedef D C::*type;
};

template struct Rob<AcessorTag<int>, &C::m_i>;

int &get_c(C &cls) {
    return cls.*get(AcessorTag<int>());
}

int main()
{
    C c(13);
    std::cout << get_c(c);
    return 0;
}

您能解释一下为什么这段代码可以编译吗?这里发生的几乎所有事情都是 1) 我们将指向成员的指针作为参数传递给结构模板 2) 我们声明一个友元函数,它只返回指向成员的指针。

这是标准的 C++ 吗? (我在 VS 2015 上测试过)

get函数是struct Rob<>的 friend 但它不是 struct C 的 friend .无论如何,struct C似乎没有 friend ,为什么它的私有(private)成员可以访问?

谢谢!

最佳答案

除了缺少 get 函数的前向声明之外,这段代码应该可以正常工作并且符合标准。由于适用于模板的显式实例化定义的特殊规则,此代码有效:

17.8.2 Explicit instantiation [temp.explicit]

14 The usual access checking rules do not apply to names used to specify explicit instantiations. [Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. —end note ]

这样写

template struct Rob<AcessorTag<int>, &C::m_i>;

将绕过通常的访问检查,并为 get 函数体提供指向其他不可访问成员的指针。

this answer 中很好地描述了这种花哨规则的动机。 .

关于c++ - 为什么此代码允许访问私有(private)变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49758436/

相关文章:

javascript - 在模板中启动 dijis

c++ - Lambda 表达式作为 C++14 中的类模板参数

C++ 找不到在继承自当前模板类的模板基类中定义的类型

Java - 扩展 ArrayList,使方法私有(private)化

c++ - 在 GCC 中为类使用属性打包

c++ - 分布式进程异步通信的最佳方式是什么?

c++ - DeskTop计算器出现问题。 C++程式语言

c++ - 插入双向链表

iOS 应用程序被拒绝 - 私有(private)符号 mach_init_routine

node.js - 如何在 Windows 中设置 npm 环境变量