问题描述
从博客文章 :
template<typename Tag, typename Tag::type M> 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<A_f, &A::a>; int main() { A a(42); std::cout << "proof: " << a.*get(A_f()) << std::endl; }
如何 get 可以调用 a 对象,因为它未定义在类A ?
how get function can be call from a object since its not defined inside class A ?
EDIT:
我不明白为什么get必须有Tag作为参数而不是 a 。* get< A_f>()
=>确定是由于ADL机制
I don't understand why get must have Tag as parameter instead of a.*get<A_f>()=> ok it's due to ADL mechanism
推荐答案
p>您不是从 a 调用 get !实际上,get返回是指向 A 中的成员的类指针,类型为 int A :: * 您需要一个 A 的实例来访问该值。
You are not calling get from a! Actually what get return is a class pointer to a member inside A and type of it is int A::* so you need an instance of A to access that value.
例如,让我玩一些代码:
For example let me play a little with your code:
struct A { A(int a):a(a) { } int b; private: int a; }; void test() { auto p = &A::b; std::cout << a.*p << std::endl; }
我调用 p 从 a ? a 没有 p ,这正是在您的代码中发生的情况, get 函数返回& A :: a ,并使用 a 读取其值!
Did I call p from inside a? a does not have p, this is exactly what happened in your code, get function return &A::a and you use a to read its value! that's all, nothing is wrong and I think it will be compiled in all compilers.
这里还有一个问题是:为什么C ++允许声明模板使用<$ c的私有成员$ c> A 。 C ++标准说:
One other question here is: Why C++ allow declaring template using private member of A. C++ standard say:
但是如果你尝试实例化或甚至 typedef 指定的模板,那么你会得到一个错误。
稍微修改你的例子:
But if you try to instantiate or even typedef specified template then you get an error.Let's modify your example slightly:
struct A { private: int a; friend void f(); }; // Explicit instantiation - OK, no access checks template struct Rob<A_f, &A::a>; // Try to use the type in some way - get an error. struct Rob<A_f, &A::a> r; // error typedef struct Rob<A_f, &A::a> R; // error void g(struct Rob<A_f, &A::a>); // error // However, it's Ok inside a friend function. void f() { Rob<A_f, &A::a> r; // OK typedef Rob<A_f, &A::a> R; // OK }
这篇关于使用模板技巧访问私有成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!