Search code examples
c++templatesc++11decltype

Deduce member function return type using a class member function object


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


Solution

  • 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.