I need to get the result of a member function of a template parameter of a class. Unfortunately, I am bound to C++03 and cannot use decltype, but I can use tr1::result_of. I tried the following code, but that did not work with my compiler (gcc 4.3, I also cannot change this):
#include <tr1/functional>
struct ReturnType {};
struct O
{
ReturnType f();
};
template<typename T> struct A
{
typename std::tr1::result_of<(&T::f)(T*)>::type f();
};
void f()
{
A<O> a;
ReturnType x = a.f();
}
The above code reflects my understanding of result_of<Fn(ArgTypes ...)
:
If Fn is a pointer to a non-static member function, and the first type in ArgTypes is the class the member belongs to (or a reference to it, or a reference to a derived type, or a pointer to it), and the remaining types in ArgTypes describe its arguments.
I pass it a pointer to a member function and specify the first parameter type to be a pointer to the class. However, the compiler prints the following error:
result_of.cpp:12: error: `&' cannot appear in a constant-expression
result_of.cpp:12: error: a function call cannot appear in a constant-expression
result_of.cpp:12: error: template argument 1 is invalid
result_of.cpp:12: error: invalid use of ‘::’
result_of.cpp:12: error: expected ‘;’ before ‘f’
result_of.cpp: In function ‘void f()’:
result_of.cpp:18: error: ‘struct A<O>’ has no member named ‘f’
I cannot change the class O to e.g. add a result typedef, so I must be able to get the return type at compile time.
The std::tr1::result_of
requires a type parameter. You are passing it a non-type (a pointer to member).
This makes std::tr1::result_of
very limited in the absence of decltype
. For instance you can use it in a wrapper function:
template <typename Ct, typename Arg>
void some_wrapper(Ct fun, Arg arg)
{
typedef typename std::tr1::result_of<Ct(Arg)>::type ret;
ret result = fun(arg);
// ... do something with result
}
but you cannot use it like you are trying to.