One of my personal experiments to understand some of the C++0x features: I'm trying to pass a function pointer to a template function to execute. Eventually the execution is supposed to happen in a different thread. But with all the different types of functions, I can't get the templates to work.
#include <functional>
int foo(void) {return 2;}
class bar {
public:
int operator() (void) {return 4;};
int something(int a) {return a;};
};
template <class C>
int func(C&& c)
{
//typedef typename std::result_of< C() >::type result_type;
typedef typename std::conditional<
std::is_pointer< C >::value,
std::result_of< C() >::type,
std::conditional<
std::is_object< C >::value,
std::result_of< typename C::operator() >::type,
void>
>::type result_type;
result_type result = c();
return result;
}
int main(int argc, char* argv[])
{
// call with a function pointer
func(foo);
// call with a member function
bar b;
func(b);
// call with a bind expression
func(std::bind(&bar::something, b, 42));
// call with a lambda expression
func( [](void)->int {return 12;} );
return 0;
}
The result_of template alone doesn't seem to be able to find the operator() in class bar and the clunky conditional I created doesn't compile. Any ideas? Will I have additional problems with const functions?
How about using decltype
?
template <class C>
auto func(C&& c) -> decltype(c()) {
auto result = c();
return result;
}
If i understand the C++0x draft right the following should actually be sufficient:
typedef typename std::result_of<C()>::type result_type;
Using that instead of your conditional expression, it compiles fine on gcc4.5 - maybe you have found a bug in whatever compiler you are using?
I got your template to instantiate, but GCC complains about possibly every use of result_of
.
template <class C>
int func(C&& c)
{
//typedef typename std::result_of< C() >::type result_type;
typedef typename std::conditional<
std::is_pointer< C >::value,
// C++0x still requires "typename" sprinkles:
typename std::result_of< C() >::type,
typename std::conditional<
std::is_object< C >::value,
// result_of takes a *type* as an argument, not an object:
//typename std::result_of< decltype( &C::operator() ) >::type,
// Or better:
typename std::result_of< C >::type,
void>
>::type result_type;
result_type result = c();
return result;
}
int main(int argc, char* argv[])
{
// according to GCC, func(foo) passes a function reference.
func(foo);
First error message:
rof.cpp:23:17: error: invalid use of incomplete type 'struct std::result_of<int (&)()>'
result_of
is implemented as specified in the standard, so it appears that GCC cannot match the pseudo-prototype syntax in the partial specialization declaration.
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