Since whatever result you obtain depends on the template parameter, typedef typename
is necessary.
decltype
is a C++0x extension which isn't yet fully supported by GCC. It is an operator which takes an expression and returns a type.
typedef typename decltype( T().toCPD() ) D; // can't use T:: as it's nonstatic
If T()
isn't a valid (T
not default-constructible) you will want declval
which takes a type and returns a meaningless, unconstructed value of that type.
typedef typename decltype( declval<T>().toCPD() ) D; // YUCK!
typeof
is a nonstandard, older alias for decltype
. Here is its documentation under GCC.
result_of
is a TR1 extension which should be more portable, but doesn't seem to work at all in GCC 4.2.1 and 4.5. It is a template which takes a function type (such as int(void)
or int(*)(void)
) and returns that function's return type.
Unfortunately, it is not specified to work with pointer-to-member-function (ptmf) types. Furthermore, although non-pointer member function objects (i.e. a hypothetical T::toCPD
with no &
) have the type of regular functions (thanks to Litb for the tip), there is no way to name such an object in C++03 at least, and I'm not aware of any way to form such a type from a ptmf type in C++03 or TR1. std::remove_ptr
in C++0x might be capable of such, but it's unclear from the spec and doesn't work in GCC 4.5.
Even if you do have a non-member function, a template can't resolve the type (B ()
) of an object (B foo()
). Only decltype
can do that (or function template type deduction, which we can't use here).
Maybe there is a way to use result_of
in such a way as to remove the need for declval
, but I can't find it.
On the other hand, it's quite easy to write result_of_ptmf
for ptmf types:
template< class T >
struct result_of_ptmf {};
template< class R, class C, class ... A >
struct result_of_ptmf< R (C::*)( A ... ) > {
typedef R type;
};
(in C++0x anyway) and use it:
typedef typename result_of_ptmf< decltype( &T::toCPD ) >::type D;
This works fine in GCC 4.5.