chaosink
chaosink

Reputation: 1483

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> > > >'

Upvotes: 1

Views: 47

Answers (1)

Daniel Langr
Daniel Langr

Reputation: 23497

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.

Upvotes: 4

Related Questions