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.
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.
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 .
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.
[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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With