5

I don't really know how to describe this, but this is the code:

class A : public std::vector<A>
{
};

//....

A a;
a.push_back(a);

What does it do and why would you do this?

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625

3 Answers3

4

This is curiously recurring template pattern(CRTP).
It allows you to implement static polymorphism.

However, it is a bad practice to use std::vector as a base class because it does not have a virtual destructor.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • I just used vector because I didn't want to create a template class just to prove a point :). But you're right. Will look into it. Thanks – Luchian Grigore Jan 29 '12 at 15:37
1

Since it's a vector of As and not A*s, a cannot contain itself per se. But that push_back will add to the vector a copy of a at the time of the call.

Example:

#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;
}

And the output:

0xbff4fa20=[
  0x9ec2008=[]
]

0xbff4fa20=[
  0x9ec2018=[]
  0x9ec2024=[
    0x9ec2038=[]
  ]
]

0xbff4fa20=[
  0x9ec2048=[]
  0x9ec2054=[
    0x9ec20a0=[]
  ]
  0x9ec2060=[
    0x9ec2080=[]
    0x9ec208c=[
      0x9ec2008=[]
    ]
  ]
]
Vlad
  • 18,195
  • 4
  • 41
  • 71
0

The subclass is to terminate the generics. The vector can only contain objects of type A, not arbitrary vectors.

Now, why you are building an object containing itself I do not know. But there are reasons to do so. For example, for unit testing, to ensure that an algorithm is able to handle collections that contain loops. A naive algorithm will probably run into an infinite loop, thus fail the unit test.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194