如何在C ++中将成员变量指针转换为泛型类型 [英] How to cast member variable pointer to generic type in C++

查看:138
本文介绍了如何在C ++中将成员变量指针转换为泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中有类似的代码:

I have code similar to this in my application:

class A
{
  public: int b;
}

class C
{
  public: int d;
}

void DoThings (void *arg1, MYSTERYTYPE arg2);

A obj_a;
C obj_c;

DoThings(&obj_a, &A::b);
DoThings(&obj_c, &C::d);

问题是MYSTERYTYPE应该是什么?

The question is - What should MYSTERYTYPE be? neither void* nor int work, despite the value &A::b being printed just fine if you output it through a printf.

说明:是,&A;如果你通过printf输出的话,无论是void *还是int工作,尽管值& :: b在C ++下定义。是的,我想获得类成员的偏移量。是的,我很棘手。

Clarifications: Yes, &A::b is defined under C++. Yes, I am trying to get the offset to a class member. Yes, I am being tricky.

编辑:哦,我可以使用offsetof()。非常感谢。

Oh I can use offsetof(). Thanks anyway.

推荐答案

你有一个数据成员指针指向两个不相关的类。嗯,你找不到一个可以容纳两个指针的常见类型。它只有在函数参数是指向成员的数据成员指针时才会起作用,因为如果基数包含它,它也保证包含成员:​​

You have a data member pointer to two unrelated classes. Well, you can't find a common type that can hold both pointers. It will only work if the function parameter is a data member pointer to a member of the derived, because it's guaranteed to contain the member too, if a base contains it:

struct a { int c; }; struct b : a { }; int main() { int b::*d = &a::c; }


strong> Update :我想我应该写为什么上面的转换从 a :: * b :: * implicitly。毕竟,我们通常有 b * a * !请考虑:

Update: I think i should write why the above converts from a::* to b::* implicitly. After all, we usually have b* to a* ! Consider:

struct a { };
struct b : a { int c; };
struct e : a { };
int main() { int a::*d = &b::c; e e_; (e_.*d) = 10; /* oops! */ }

如果上述操作有效,上面的不是有效,因为从 b :: * a :: * 不是隐式的。正如你所看到的,我们为b :: c分配了一个指针,然后我们可以使用一个不包含它的类来解引用它。 ( e )。编译器强制执行这个顺序:

If the above would be valid, you would really much screw up. The above is not valid, because conversion from b::* to a::* is not implicit. As you see, we assigned a pointer to b::c, and then we could dereference it using a class that doesn't contain it at all! (e). The compiler enforces this order:

int main() { int b::*d = &b::c; e e_; (e_.*d) = 10; /* bug! */ }

现在无法编译,因为 e 不是从成员指针指针所属的类 b 派生的。好!然而,以下是非常有效的并且编译,当然(改变的类 a b ):

It fails to compile now, because e is not derived from b, the class the member pointer pointer belongs to. Good! The following, however, is very valid and compiles, of course (changed classes a and b):

struct a { int c; };
struct b : a { };
struct e : a { };
int main() { int e::*d = &a::c; e e_; (e_.*d) = 10; /* works! */ }


为了使它适用于你的情况,你必须使你的函数成为一个模板:

To make it work for your case, you have to make your function a template:

template<typename Class>
void DoThings (int Class::*arg) { /* do something with arg... */ }


b $ b

现在,编译器将自动推导出给定成员指针所属的类。您必须在成员指针旁边传递实例才能使用它:

Now, the compiler will auto-deduce the right class that the given member pointer belongs too. You will have to pass the instance alongside of the member pointer to actually make use of it:

template<typename Class>
void DoThings (Class & t, int Class::*arg) { 
    /* do something with arg... */ 
    (t.*arg) = 10;
}

如果你只想设置一些成员, DoThings,以下足够:

If you just want to set some member you already know at the time you write DoThings, the following suffices:

template<typename Class>
void DoThings (Class & t) {  
    t.c = 10;
}

这篇关于如何在C ++中将成员变量指针转换为泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆