Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

templates

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?

like image 806
Luchian Grigore Avatar asked Jan 29 '12 15:01

Luchian Grigore


2 Answers

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.

like image 109
Alok Save Avatar answered Oct 12 '22 07:10

Alok Save


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=[]
    ]
  ]
]
like image 38
Vlad Avatar answered Oct 12 '22 08:10

Vlad