一个类是如何从一个专门针对它自己的模板派生出来的

How is it possible for a class to be derived from a template specialized on itself?

本文关键字:一个 自己的 它自己 派生      更新时间:2023-10-16

我真的不知道如何描述它,但这是代码:

class A : public std::vector<A>
{
};
//....
A a;
a.push_back(a);

它做什么?你为什么要这样做?

这是奇怪的重复模板模式(CRTP)
它允许您实现静态多态性

但是,使用std::vector作为基类是一种糟糕的做法,因为它没有虚拟析构函数。

由于它是As的向量,而不是A*s的向量,因此a本身不能包含它自己。但是push_back将在调用时向向量中添加a的副本。

示例:

#include <vector>
#include <iostream>
using namespace std;
class A : public std::vector<A>
{
    public:
        void print(int level=0){
            for (int i=0;i<level;i++) cout<<"  ";
            cout << "0x" << hex << (unsigned int)this << "=[";
            if (size()){
                cout  << endl;
                for (int i=0; i<size(); i++)
                    (*this)[i].print(level+1);
                for (int i=0;i<level;i++) cout<<"  ";
            }
            cout <<"]"<<endl;
            if(!level) cout << endl;
        }
};
int main(){
    A a;
    for (int i=1;i<=3;i++){
        a.push_back(a);
        a.print();
    }
    return 0;
}

输出:

0xbff4fa20=[
  0x9ec2008=[]
]
0xbff4fa20=[
  0x9ec2018=[]
  0x9ec2024=[
    0x9ec2038=[]
  ]
]
0xbff4fa20=[
  0x9ec2048=[]
  0x9ec2054=[
    0x9ec20a0=[]
  ]
  0x9ec2060=[
    0x9ec2080=[]
    0x9ec208c=[
      0x9ec2008=[]
    ]
  ]
]

子类用于终止泛型。矢量只能包含A类型的对象,而不能包含任意矢量。

现在,我不知道你为什么要构建一个包含自己的对象。但这样做是有原因的。例如,对于单元测试,为了确保算法能够处理包含循环的集合。一个天真的算法可能会运行到一个无限循环中,从而使单元测试失败。

相关文章: