gpt4 book ai didi

c++ - Crazy C++ 模板 - 访问类的各个属性的模板

转载 作者:IT老高 更新时间:2023-10-28 22:25:41 27 4
gpt4 key购买 nike

我是一名 C++ 程序员新手,但我认为我对 C++ 的了解已经足够了,直到今天我在工作中遇到了这样的代码,却无法理解它的实际工作原理。

class Object
{
};

template <
class PropObject,
class PropType,
PropType PropObject::* Prop
>
class PropReader
{
public:
void print(Object& o)
{
PropObject& po = static_cast<PropObject &>(o);
PropType& t = po.*Prop;

cout << t << "\n";
}
};

class Student : public Object
{
public:
int age;
int grade;
};

int _tmain(int argc, _TCHAR* argv[])
{
Student s;
s.age = 10;
s.grade = 5;

PropReader<Student, int, &Student::age> r;
PropReader<Student, int, &Student::grade> r2;

r.print(s);
r2.print(s);
}

我想我理解的程度很高。但是模板声明中的这个特殊的 PropType PropObject::* Prop 困扰着我。这是什么意思?我正在寻找 C++ 专家的解释。我想了解它,以便更好地使用它。不过看起来很有用。

最佳答案

C++ 模板以将类型作为参数而闻名,但它们也可以对其他类型的数据进行参数化。例如,您可以将一个类模板化为一个整数,如下所示:

template <typename T, unsigned int N> class Array {
private:
T array[N];

public:
/* ... */
};

模板也可以通过指针进行参数化,只要指针满足某些标准(例如,它必须评估为可以在编译时确定的地址)。例如,这是完全合法的:

template <int* Pointer> class ThisIsLegal {
public:
void doSomething() {
*Pointer = 137;
}
};

在您的代码中,模板通过指向类成员的指针 进行参数化。指向类成员的指针类似于指针,因为它间接引用了某个对象。但是,它不是指向一个对象,而是指向一个类中的一个字段。这个想法是,您可以取消引用相对于某个对象的指向类成员的指针,以从类中选择该字段。这是一个指向类成员的简单示例:

struct MyStruct {
int x, y;
};

int main() {
MyStruct ms;
ms.x = 137;
ms.y = 42;

int MyStruct::* ptr; // Declare a pointer to a class member.
ptr = &MyStruct::x; // Now points to the field 'x'

ms.*ptr = 0; // Set the 'x' field of ms to be zero.
}

注意声明类成员指针的语法是

Type ContainingClass::* pointerName;

所以在上面的代码中,int MyStruct::* ptr表示“指向 int 类中的 MyStruct 的指针。

在您发布的代码中,模板声明如下所示:

template <
class PropObject,
class PropType,
PropType PropObject::* Prop
>
class PropReader

让我们看看这意味着什么。将要读取其属性的前两个模板参数对象和 PropType ,该属性的类型。”模板的最后一个参数是一个名为 Prop 的指向类成员的指针,它指向 PropObject 内的 PropType 类型的字段。例如,您可以实例化它带有 MyStruct 的模板如下:

PropReader<MyStruct, int, &MyStruct::x> myPropReader;

现在,让我们看看其余代码的作用。此类模板正文转载于此:

void print(Object& o)
{
PropObject& po = static_cast<PropObject &>(o);
PropType& t = po.*Prop;

cout << t << "\n";
}

其中一些内容很容易阅读。该函数的参数是对 Object 的引用。命名为 o ,最后一行打印出一些字段。这两行很棘手:

PropObject& po = static_cast<PropObject &>(o);
PropType& t = po.*Prop;

第一行是一个类型转换,上面写着“尝试将参数 o 转换为 PropObject 类型的引用。我猜这个想法是 Object 是很多不同的对象。函数的参数只是一个普通的 Object ,这个转换试图将它转换为适当类型的东西(回想一下 PropObject 是模板参数,说明对象的类型是什么)。因为这使用 static_cast ,如果未定义转换(例如,您尝试通过 intvector<string> 实例化模板),代码将无法编译。否则,代码相信转换是安全的,然后获取类型为 PropObject 的对参数所指内容的引用。

最后,最后一行是

PropType& t = po.*Prop;

这使用了我之前提到的指向类成员的指针解引用语法来表示“选择 Prop (模板参数)指向的字段,然后存储一个名为 t 的引用。

所以,简而言之,就是模板

  1. 询问您某些对象的类型。
  2. 询问您该对象中某个字段的类型。
  3. 要求您提供指向该对象中字段的指针。
  4. 提供print给定对象的函数会尝试打印出该字段。

哇!那很棘手!希望这会有所帮助!

关于c++ - Crazy C++ 模板 - 访问类的各个属性的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6784448/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com