如何使用带模板的类成员的尾随返回类型 [英] How to use trailing return type with a templated class member

查看:123
本文介绍了如何使用带模板的类成员的尾随返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现以下类:

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;
};

我使用尾随返回类型的原因是因为我不知道m_container是否为const,所以我让编译器为我解决.但是,出现以下编译器错误:

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:在其中没有名为"m_container"的成员 'stdx :: reverse_adaptor>>'

/Users/mark/Blah/Stdx.h:77:40: No member named 'm_container' in 'stdx::reverse_adaptor > >'

我认为这可能与模板类型的多阶段传递有关,因此将其更改为decltype(this->m_container.rbegin()),但这也不起作用.

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.

如何使它正常工作?

示例- http://ideone.com/ekVYlH

推荐答案

函数的跟踪返回类型是其"签名"(声明)的一部分,而不是其"body"(定义),因此,它只能看到之前声明的名称.

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.

在声明您的begin成员函数时,尚未声明m_container. (请注意,该问题并不特定于模板类.)

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

  • 您可以将m_container的声明在类定义中上移(但是这会迫使您将私有成员放在公共接口之前,这与通常的做法相反……).

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

您可以使用 declval 解决:将m_container替换为<decltype中的c6>: http://ideone.com/aQ8Apa

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

(如评论中所述,在C ++ 14中,您可以删除尾随的返回类型,而只需将decltype(auto)用作常规"返回类型.)

(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;
}

其中名称不能在声明之前使用(第一个decltype(m_data)违反).

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

这篇关于如何使用带模板的类成员的尾随返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆