How to use trailing return type with a templated class member

c++, c++11, trailing-return-type

Solution

The trailing-return-type of a function is part of its “signature” (declaration), not of its “body” (definition), and as such, it only sees names that were declared before.

At the point where you declare your `begin` member function, `m_container` hasn't been declared yet. (Note that the issue is not specific to template classes.)

You could move the declaration of `m_container` up in the class definition (but it forces you to put private members before public interface, which is contrary to common practice...).

You can work-around with `declval`: replace `m_container` with `std::declval<Container&>()` inside the `decltype`: http://ideone.com/aQ8Apa

(As said in the comments, in C++14 you'll be able to drop the trailing return type and just use `decltype(auto)` as the “normal” return type.)

Addendum: As for why you can use not-yet-declared members inside the in-class body of a member function but not in the trailing return type, it's because the following:

class Foo {
public:
    auto data() const -> decltype(m_data)
    {
        return m_data;
    }
private:
    SomeType m_data;
};

will be [disclaimer: informal wording!] kind of “rewritten by the compiler” into something equivalent to this:

class Foo {
public:
    inline auto data() const -> decltype(m_data); // declaration only
private:
    SomeType m_data;
};

// at this point, all members have been declared

inline auto Foo::data() const -> decltype(m_data) // definition
{
    return m_data;
}

where a name cannot be used before its declaration (which the first `decltype(m_data)` violates).

Problem

I'm trying to implement the following class: ``` template <typename Container> class reverse_adaptor { public: // Construction reverse_adaptor(Container &container) : m_container(container) {} public: // STL container static polymorphism auto begin() const -> decltype(m_container.rbegin()) { return m_container.rbegin(); } auto end() const -> decltype(m_container.rend()) { return m_container.rend(); } private: // Members Container &m_container; }; ``` The reason I'm using the trailing return type is because I don't know if m_container will be const or not, so I let the compiler work it out for me. However, I'm getting the following compiler errors: /Users/mark/Blah/Stdx.h:77:40: No member named 'm_container' in 'stdx::reverse_adaptor > >' I thought it might be related to the multi-stage pass of templated types, so changed it to read `decltype(this->m_container.rbegin())`, but that didn't work either. How can I get this to work? Example - http://ideone.com/ekVYlH

Original source