Creating a “linked list” of type “compilation” with alternating patterns

I reflected on possible implementations of std::tuple (and any similar template classes with a variable number of "members" defined at compile time), and I thought that maybe you could create a "recursive type" that looked like a linked list. I tried to compile the following test script:

 template <typename FirstType, typename... OtherTypes> class TupleLite { public: FirstType type_; TupleLite<OtherTypes...> other_types_; }; int main() { TupleLite<int,double> mytuple; } 

The class itself compiles without errors, but the instance throws the wrong number of template arguments (0, should be 1 or more) error. I believe this is because TupleLite<int, double> trying to create an instance of TupleLite<double> , which is trying to create an instance of TupleLite<> for which there is no correct definition.

Is it possible to save this "class with recursive size"? I tried to define the "specialization without arguments" TupleLite as follows:

 template <> class TupleLite {} 

.... but this does not seem to work, although g++ and clang++ do not seem to agree on why.

Of g++ most relevant errors are as follows:

 error: template specifiers not specified in declaration of 'template<class FirstType, class ... OtherTypes> class TupleLite' class TupleLite ^ error: wrong number of template arguments (0, should be 1 or more) TupleLite<OtherTypes...> other_types_; ^ 

clang++ , however, says:

 error: extraneous 'template<>' in declaration of class 'TupleLite' template <> ^ error: redefinition of 'TupleLite' as different kind of symbol class TupleLite ^ 
+5
source share
1 answer

The basic definition of a TupleLite template indicates that it requires at least one template argument, FirstType . Since this is not what you want to express, provide an initial template indent that will also handle the empty case as follows:

 template <typename...> class TupleLite{}; 

And one partial specialization:

 template <typename FirstType, typename... OtherTypes> class TupleLite<FirstType, OtherTypes...> { public: FirstType type_; TupleLite<OtherTypes...> other_types_; }; 

Demo version of Coliru .

EDIT: Thanks to Nikos for pointing out that an empty spec is not needed in this case.

+3
source

Source: https://habr.com/ru/post/1216244/


All Articles