c++ - Deducing template parameter from functor argument type -


this question has answer here:

i have following code meant accept qt qvariant , apply functor if variant contains value:

template<typename t, typename functor> inline qvariant map(const qvariant& v, functor f) {     return v.isvalid()             ? qvariant{f(qvariant_cast<t>(v))}             : v; } 

my problem compiler cannot deduce type of t when invoke function as

map(somefuncreturningqvariant(), [](const qbytearray& array) -> qstring {     return array.tostring(); }); 

the compiler complains (cleaned original error, has longer type names):

error: no matching function call `map(qvariant, <lambda(const qbytearray&)>)` note: candidate is:     template<class t, class functor> qvariant map(const qvariant&, functor). note: template argument deduction/substitution failed:       couldn't deduce template parameter 't' 

this because qvariant erases type of object contains @ runtime. (it still knows internally, boost::any, , qvariant_cast<t>() gets original object back).

how can capture type of variable passed functor , use elsewhere? alternatively, how can specify functor takes parameter of type t? (i suspect these same question, or @ least have same answer.)

note approach works fine std::optional, because types not erased:

using std::experimental::optional;  template<typename t, typename functor> inline auto map(const optional<t>& v, functor f) -> optional<decltype(f(*v))> {     return v ? optional<decltype(f(*v))>{f(*v)}              : v; } 

also note qvariant code works fine if manually specify type:

map<qbytearray>(somefuncreturningqvariant(), [](const qbytearray& array) -> qstring {     return array.tostring(); }); 

but of course, uglier.

basically want is: given functor, f, identify decayed type of first argument.

to end, need function_traits, can do:

template <typename f> using first_arg = std::decay_t<typename function_traits<f>::template arg<0>::type>; 

which use:

template<typename functor> inline qvariant map(const qvariant& v, functor f) {     using t = first_arg<functor>;      return v.isvalid()             ? qvariant{f(qvariant_cast<t>(v))}             : v; } 

Comments

Popular posts from this blog

OpenCV OpenCL: Convert Mat to Bitmap in JNI Layer for Android -

android - org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope -

python - How to remove the Xframe Options header in django? -