C ++ 14 auto lambda can accept Obj <std :: tuple <void>> - but template functions can't?

Below is a program that fully demonstrates the problem I am seeing.

First, I start with an object that is defined by grouping other types, I started using std :: tuple <> to control the grouping.

template <typename> class object; template <typename... Rs> class object<std::tuple<Rs...> > { }; 

I assume that these objects can be of type void scattered in the "package". I already know that I cannot "instantiate" a tuple of this type (see Void Type in std :: tuple )

I want to pass these objects, maybe copy / move them ... none of my data members is a tuple of these types. In fact, I can reproduce the problem using the above definition of an empty object.

I can make it work using something like:

 template <typename... Rs> struct TGrp {}; template <typename> class object; template <typename... Rs> class object<TGrp<Rs...> > { }; 

These types of “grouping” structures are often used in variational recursion, and they are designed to never be created / used. Just group template arguments.

However, I want the signature of the “object” to consist of “user-expected” types / names.

Basically, I experimented with any possible way of passing one of these objects around when std::tuple used to “group” and can only find one way: auto lambdas.

Can anyone explain:

  • why can an “auto” lambda work for this?

    something about template deduction delay? like diff b / w "auto" and "decltype (auto)"?

  • how to “create” a function parameter to accept one of these objects.

- thanks to all of you for any information about this oddity

Example:

 #include <tuple> #include <iostream> #define GRP std::tuple // IF 'tuple' used: compile error where noted below //#define GRP TGrp // if THIS is used: all works, and TGrp() is never constructed // Grouping mechanism template <typename... Ts> struct TGrp { TGrp() { std::cout << "Never printed message\n"; } }; // MAIN OBJECT (empty for forum question) template <typename> class object; template <typename... Rs> class object<GRP<Rs...> > { }; // Regular function (does NOT work) void takeobj(object<GRP<void> >& obj) { (void)obj; } // Lambda - taking anything... (only thing I could make WORK) auto takeobj_lambda = [](auto obj) { (void)obj; }; // Template func - taking anything (does NOT work) template <typename T> void takeobj_templ_norm(T obj) { (void)obj; } template <typename T> void takeobj_templ_clref(const T& obj) { (void)obj; } template <typename T> void takeobj_templ_lref(T& obj) { (void)obj; } template <typename T> void takeobj_templ_rref(T&& obj) { (void)obj; } int main() { object<GRP<void> > oval; //takeobj(oval); // <-- causes compile error takeobj_lambda(oval); // works //takeobj_templ_norm(oval); // <-- also error //takeobj_templ_clref(oval); // <-- also error //takeobj_templ_lref(oval); // <-- also error //takeobj_templ_rref(oval); // <-- also error return 0; } 

Edit : adding reduced playback:

 #include <tuple> // MAIN OBJECT (empty for forum question) template <typename> class object; template <typename... Rs> class object<std::tuple<Rs...> > { }; // Regular function (does NOT work) void takeobj(object<std::tuple<void> >& obj) { (void)obj; } // Lambda - taking anything... (only thing I could make WORK) auto takeobj_lambda = [](auto obj) { (void)obj; }; int main() { object<std::tuple<void> > oval; //takeobj(oval); // <-- causes compile error takeobj_lambda(oval); // works return 0; } 
+5
source share
1 answer

std::tuple<void> is the associated class object<std::tuple<void>> , and so in an unqualified call that performs an argument-dependent search, std::tuple<void> is created to look for any friend functions that could be defined in line. This message is causing an error.

An argument-dependent analysis is not performed if the called thing does not name a function or function template; therefore the use of lambda works - takeobj_lambda is an object.

If you use either a qualified call ( ::takeobj(oval) ) or in brackets takeobj ( (takeobj)(oval) ), then compile the code. Both of them disable ADL.

+5
source

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


All Articles