Вопрос

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

Это было полезно?

Решение

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top