How to use trailing return type with a templated class member

后端 未结 2 400
-上瘾入骨i
-上瘾入骨i 2021-01-22 23:38

I\'m trying to implement the following class:

template 
class reverse_adaptor
{
public: // Construction
    reverse_adaptor(Container &         


        
2条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-23 00:33

    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() 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).

提交回复
热议问题