
On Tuesday 04 September 2012 10:06:32 Mathias Gaunard wrote:
On 04/09/2012 08:59, Andrey Semashev wrote:
I suppose, in such cases additional
specializations are still needed: struct my_foo {
template< typename > struct result;
template< typename ArgT > struct result< my_foo(ArgT const&) >;
I assume you meant
template< typename ArgT > struct result< my_foo(ArgT const&) > { typedef ArgT type; };
there?
No, my intent was to disable the const& version, because the operator() doesn't support it. However, now that you mentioned it, what I really wanted to express is that my operator() requires a non-const lvalue argument and the way operator() is written it doesn't communicate that clearly (because ArgT can be const).
template< typename ArgT > struct result< my_foo(ArgT&) > {
typedef ArgT type;
};
template< typename ArgT > ArgT operator() (ArgT& arg) const {
return arg;
}
};
1) doesn't support result_of<my_foo(int)> 2) not always the same type as what operator() returns (consider a const lvalue passed to operator()) 3) needless repetition
You probably wanted to write
struct my_foo { template<class Sig> struct result;
template<class This, class A0> struct result<This(A0)> : strip<A0> {};
template<class A0> typename remove_const<A0>::type operator()(A0& a0) const { return a0; } };
No, see my note above. For sake of the example, let's assume my_foo does a post-increment on its argument. template<class A0> typename disable_if< is_const<A0>, A0 >::type operator()(A0& a0) const { return a0++; } Also, what is strip in your example? I didn't find it in type traits.