Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using declaration in variadic template

This question is inspired in the following solution to multiple inheritance overloading pseudo-ambiguity, which is a nice way to implement lambda visitors for boost::variant as proposed in this answer:

I want to do something like the following:

template <typename ReturnType, typename... Lambdas> struct lambda_visitor : public boost::static_visitor<ReturnType>, public Lambdas... {     using Lambdas...::operator(); //<--- doesn't seem to work     lambda_visitor(Lambdas... lambdas) : boost::static_visitor<ReturnType>() , Lambdas(lambdas)... { } }; 

I'm not sure what would be the right syntax of adding using clauses for packed type lists. The using clause is crucial to stop the compiler from complaining that the operator() are ambiguous, which totally are not, because they have all different signatures.

like image 496
lurscher Avatar asked Oct 24 '11 01:10

lurscher


People also ask

What is the use of using declaration?

A using declaration introduces an unqualified name as a synonym for an entity declared elsewhere. It allows a single name from a specific namespace to be used without explicit qualification in the declaration region in which it appears.

What is the use of using declaration in C++?

A using declaration in a definition of a class A allows you to introduce a name of a data member or member function from a base class of A into the scope of A .

What is Variadic template in C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.

What is a parameter pack?

[edit] A template parameter pack is a template parameter that accepts zero or more template arguments (non-types, types, or templates). A function parameter pack is a function parameter that accepts zero or more function arguments. A template with at least one parameter pack is called a variadic template.


1 Answers

Ok i found out a pretty decent solution:

basically i need to unpack one extra lambda case and apply the using clause to the unpacked lambda and the rest, but in this case, since i apparently i cannot make a variadic list of using declarations (at least i don't know the syntax, if its possible), the rest is wrapped by inheriting from the 'rest' case, like this:

template <typename ReturnType, typename... Lambdas> struct lambda_visitor;  template <typename ReturnType, typename Lambda1, typename... Lambdas> struct lambda_visitor< ReturnType, Lambda1 , Lambdas...>    : public lambda_visitor<ReturnType, Lambdas...>, public Lambda1 {      using Lambda1::operator();     using lambda_visitor< ReturnType , Lambdas...>::operator();     lambda_visitor(Lambda1 l1, Lambdas... lambdas)        : Lambda1(l1), lambda_visitor< ReturnType , Lambdas...> (lambdas...)     {} };   template <typename ReturnType, typename Lambda1> struct lambda_visitor<ReturnType, Lambda1>    : public boost::static_visitor<ReturnType>, public Lambda1 {      using Lambda1::operator();     lambda_visitor(Lambda1 l1)        : boost::static_visitor<ReturnType>(), Lambda1(l1)     {} };   template <typename ReturnType> struct lambda_visitor<ReturnType>    : public boost::static_visitor<ReturnType> {      lambda_visitor() : boost::static_visitor<ReturnType>() {} }; 

So i can do this inductively by placing two using declarations, one from the unpacked lambda type and another from the parent class, which is actually the same class with one less lambda.

like image 138
lurscher Avatar answered Sep 28 '22 03:09

lurscher