本文介绍了使用模板技巧访问私有成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从博客文章 :

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
}

这篇关于使用模板技巧访问私有成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 08:01
查看更多