c++ - How to test lambda in C++11 -


normally, test if pointer points function, use std::is_function enough.

however, cannot work lambda. since lambda object operator().

now have use both is_function , is_object check if 1 works function, below:

std::is_function<decltype(f)>::value || std::is_object<decltype(f)>::value

so i'm wondering if there better way test if 1 lambda or not?

edit:

related code:

template<typename func> void deferjob(func f, int ms=2000) {     if(! std::is_function<decltype(f)>::value             && ! std::is_object<decltype(f)>::value){         qdebug()<<"not function!";         return;     }     qtimer* t = new qtimer;     t->setsingleshot(true);     qobject::connect(t, &qtimer::timeout,             [&f, t](){         qdebug()<<"deferjob";         f();         t->deletelater();     });     t->start(ms); } 

edit2:

similar question: c++ metafunction determine whether type callable

so here thoughts may or may not helpful.

  • to create type_trait works functors, lambdas , traditional functions, think seeing if template argument convertible std::function<void()>. think cover bases in clear way.

  • as we've mentioned in comments, can't test template argument way doing. f() later in function cause compile error, , you'll never have opportunity see runtime error.

  • you can try std::enable_if. you'd need create template specializations sfinae can function choose correct implementation. use type_trait mentioned in bullet 1.

  • if did this, make implementation of other template static_assert create "better" error message.

  • that being said, compiler error messages aren't bad in first place. (at least in clang , gcc. haven't looked msvc).


this doesn't great error message, different one:

#include <cassert> #include <functional> #include <type_traits>  template <typename func> typename std::enable_if<std::is_convertible<func, std::function<void()>>::value>::type deferjob(func f, int ms=2000) { }  void normal_function() {}  int main() {     deferjob([]() {});          // works     deferjob(&normal_function); // works     deferjob(3);                // compile time error } 

in clang, error looks like:

foo.cc:15:2: error: no matching function call 'deferjob'         deferjob(3);                // compile time error         ^~~~~~~~ foo.cc:6:25: note: candidate template ignored: disabled 'enable_if' [with func = int] typename std::enable_if<std::is_convertible<func, std::function<void()>>::value>::type 

in gcc, error looks like:

foo.cc: in function ‘int main()’: foo.cc:15:12: error: no matching function call ‘deferjob(int)’   deferjob(3);                // compile time error             ^ foo.cc:15:12: note: candidate is: foo.cc:7:1: note: template<class func> typename std::enable_if<std::is_convertible<func, std::function<void()> >::value>::type deferjob(func, int)  deferjob(func f, int ms=2000) {  ^ foo.cc:7:1: note:   template argument deduction/substitution failed: foo.cc: in substitution of ‘template<class func> typename std::enable_if<std::is_convertible<func, std::function<void()> >::value>::type deferjob(func, int) [with func = int]’: foo.cc:15:12:   required here foo.cc:7:1: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’ 

we go 1 step further (although doing way makes hard extend further) , add additional function:

template <typename func> typename std::enable_if<not std::is_convertible<func, std::function<void()>>::value>::type deferjob(func f, int ms=2000) {     static_assert(false, "you should pass function"); } 

this causes clang report (at compile time):

foo.cc: in function ‘typename std::enable_if<(! std::is_convertible<func, std::function<void()> >::value)>::type deferjob(func, int)’: foo.cc:14:2: error: static assertion failed: should pass function   static_assert(false, "you should pass function"); 

but sadly, doesn't give stack trace, find far less helpful of earlier messages.


and finally, replace static assert runtime message:

template <typename func> typename std::enable_if<not std::is_convertible<func, std::function<void()>>::value>::type deferjob(func f, int ms=2000) {     qdebug() << "not function!"; } 

Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -