Search code examples
c++constructorclass-template

How to construct objects of nested class templates with the same argument?


How to construct objects of nested class templates with the same argument?

How to write the constructor to make following code compile?

template<typename T>
struct S {
    T v;

    S(T v) : v{v} {}
};

int main() {
    S<int>{0};          // OK.
    S<S<int>>{0};       // OK.
    S<S<S<int>>>{0};    // Compilation error. I want this to compile.
    S<S<S<S<int>>>>{0}; // Compilation error. I want this to compile.
    // ...              //                    I want more...
}

The Compilation errors:

no matching constructor for initialization of 'S<S<S<int> > >'
no matching constructor for initialization of 'S<S<S<S<int> > > >'

Solution

  • You can add a second converting constructor. If you want to support any type, just make this constructor templated:

    template <typename T>
    struct S {
       T v;
    
       S(T v) : v{v} {}
    
       template <typename U>
       S(U v) : v{v} {}
    };
    

    This work as follows:

       S<int>{0};          
       S<S<int>>{0};       
       S<S<S<int>>>{0};    
       S<S<S<S<int>>>>{0}; 
    
       S<double>{0.0};
       S<S<double>>{0.0};       
       S<S<S<double>>>{0.0};    
       S<S<S<S<double>>>>{0.0}; 
    

    Live demo: https://godbolt.org/z/NKEGRz

    Note that at the very bottom level, both constructors are applicable, but the non-templated one will be selected according to the C++ overloading rules.