I have been troubled for hours or days around such problems. Typically gcc wants this->
but clang does not. In some cases Foo::
also helps but there have been cases where I have given up using the member names. The following is only using the type names and (though more verbose) I think will not have any problems with either:
template<typename Base, typename Acc>
struct Foo
{
Base base;
Acc acc;
template<typename S>
using result = typename std::result_of<S>::type;
auto operator()(unsigned i) const
-> result<const Acc(result<const Base(unsigned)>)>
{ return acc(base(i)); }
};
More generally, whenever decltype(member_name)
is causing problems, you can safely use decltype(std::declval<member_type>())
where member_type
is const
-qualified if the member function using it is const
.
Even more generally, if you have a member function that is &&
, &
or const&
qualified, use member_type
, member_type&
or const member_type&
respectively in such expressions.
I have never looked into what the standard says but in practice compilers treat expressions differently in trailing return types and inside function definitions when it comes to class members.