Reputation: 22981
Edit: I feel kind of silly now. The posted code actually works with ???=decltype(acc(base(i)))
... The error was something else - highly confusing though. I will post a new question about that. Thank you for your help.
I have some code like this:
template<typename Base, typename Acc>
struct Foo
{
Base base;
Acc acc;
auto operator()(unsigned i) const -> decltype(???) // what is ???
{ return acc(base(i)); }
};
How do I get the correct return type?
I tried with decltype(acc(base(i)))
but this gives an error (using GCC 4.6.3):
there are no arguments to ‘base’ that depend on a template parameter, so a declaration of ‘base’ must be available
Upvotes: 1
Views: 590
Reputation: 7637
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.
Upvotes: 2