简体   繁体   English

尾随返回类型,decltype和const-ness

[英]Trailing return types, decltype and const-ness

I was merily experimenting with the new trailing return types, where I hit a problem with this (simplified) code 我正在试验新的尾随返回类型,我遇到了这个(简化的)代码的问题

#include <list>

class MyContainer{
  std::list<int> ints;

  auto begin( ) -> decltype(ints.begin())
  {
    return ints.begin();
  }

  auto begin( ) const -> decltype(ints.begin())
  {
    return ints.begin();
  }
};

Ignore the fact of how pointless this code is. 忽略这段代码毫无意义的事实。 The important part is the compiler error generated when using GCC 4.6.1 (with -std=c++0x flag): 重要的部分是使用GCC 4.6.1时生成的编译器错误(使用-std=c++0x标志):

In member function 'std::list<int>::iterator MyContainer::begin() const':
error: could not convert '((const MyContainer*)this)->MyContainer::ints.std::list<_Tp, _Alloc>::begin [with _Tp = int, _Alloc = std::allocator<int>, std::list<_Tp, _Alloc>::const_iterator = std::_List_const_iterator<int>]()' from 'std::list<int>::const_iterator {aka std::_List_const_iterator<int>}' to 'std::list<int>::iterator {aka std::_List_iterator<int>}'

In case you're not of fan of error involving templates, the short story is that in the body of the const version of MyContainer::begin , the expression ints.begin() returns a value of type std::list<int>::const_iterator (since ints is const in such a context). 如果您不喜欢涉及模板的错误,那么简短的故事就是在MyContainer::beginconst版本的主体中,表达式ints.begin()返回类型为std::list<int>::const_iterator的值。 std::list<int>::const_iterator (因为ints在这样的上下文中是const )。 However, decltype(ints.begin()) produces the type std::list<int>::iterator , ie decltype ignores the const qualifier of the begin method when deciding the type of the expression. 但是, decltype(ints.begin())生成类型std::list<int>::iterator ,即decltype在决定表达式的类型时忽略 begin方法的const限定符。 Unsurprisingly, a conflict in types is the result. 不出所料,结果就是类型冲突。

This seems to me to be a bug in the GCC compiler. 在我看来这是GCC编译器中的一个错误。 It would only make sense for decltype to honor the const qualifier and produce the const_iterator type. 只有使用decltype来表示const限定符并生成const_iterator类型才有意义。 Can anyone confirm or deny (maybe even explain) this? 任何人都可以确认或否认(甚至可以解释)这个吗? Maybe I am overlooking something in the mechanics of decltype , but this looks like a pretty straightforward scenario. 也许我忽略了decltype ,但这看起来非常简单。

Note: as far as I can tell, the same behaviour holds not only for std::list<int> , but for any type with member functions overloaded on const -ness which return incompatible types. 注意:据我所知,相同的行为不仅适用于std::list<int> ,而且适用于在const -ness上重载成员函数的任何类型,这些类型返回不兼容的类型。

You are correct, this is a bug. 你是对的,这是一个错误。 According to N3291, section 5.1.1, paragraph 3: 根据N3291,第5.1.1节,第3段:

If a declaration declares a member function or member function template of a class X, the expression this is a prvalue of type “pointer to cv-qualifier-seq X” between the optional cv-qualifer-seq and the end of the function-definition, member-declarator, or declarator. 如果声明声明了类X的成员函数或成员函数模板,则表达式是可选的cv-qualifer-seq和函数定义结束之间的类型为“指向cv-quali fi er-seq X的指针”的prvalue。 ,成员声明者或声明者。 It shall not appear before the optional cv-qualifier-seq and it shall not appear within the declaration of a static member function (although its type and value category are defined within a static member function as they are within a non-static member function). 它不应出现在可选的cv-quali-seq之前,它不应出现在静态成员函数的声明中(尽管它的类型和值类别是在静态成员函数中定义的,因为它们在非静态成员函数中) 。 [Note: this is because declaration matching does not occur until the complete declarator is known. [注意:这是因为在完整的声明符已知之前不会发生声明匹配。 —end note ] Unlike the object expression in other contexts, *this is not required to be of complete type for purposes of class member access (5.2.5) outside the member function body. -end note]与其他上下文中的对象表达式不同,*为了成员函数体之外的类成员访问(5.2.5),这不需要是完整类型。 [Note: only class members declared prior to the declaration are visible. [注意:只有在声明之前声明的类成员才可见。 —end note ] - 尾注]

But this was a recent change between the last working draft and N3291. 但这是最近一份工作草案与N3291之间的最新变化。 So GCC was right less than 6 months ago; 所以GCC在不到6个月前是对的; that's the danger of writing code to a moving specification. 这就是将代码编写到移动规范中的危险。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM