如何使用带模板的类成员的尾随返回类型 [英] How to use trailing return type with a templated class member
问题描述
我正在尝试实现以下类:
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.
如何使它正常工作?
推荐答案
函数的跟踪返回类型是其"签名"(声明)的一部分,而不是其"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屋!