根据规范,const为const引用需要const吗?

时间:2014-11-20 19:22:53

标签: c++ c++11

编辑我错过了一个重要的细节,地图是const。该示例已更新。

考虑

const std::map<int, int> ints;
auto& it = ints.find(0);

回顾C ++(工作草案)规范以及Stroustrup的“The C ++ Programming Language,FOURTH EDITION”,我无法确定是否需要const(我确实认为{{1}明确地修改了类型在风格上更好,但这不是我的问题)。 Visual Studio 2013编译得很好,推导出const

我知道裸const(即autoconst之类的装饰品)不会推断出非常规的非参照类型。

在Stroupstrup的书中的每个例子中,他使用&而不是const auto&来表示这种情况。 编辑但他没有说明使用auto&的选项/需要,他们只是const的例子。

gcc 4.9.1无法编译它,xcode for mac也是如此: auto

这些编译器选择吗?规范是否说明了这一点?

感谢。

2 个答案:

答案 0 :(得分:1)

是的,这种行为完全是标准规定的:

  

[C++11: 7.1.6.4/5]:在本节未明确允许的上下文中使用auto的程序格式不正确。

     

[C++11: 7.1.6.4/6]:根据8.3确定 declarator-id 的类型后,确定使用 declarator-id 的声明变量的类型从其初始化程序的类型使用模板参数推导的规则。设T为已为变量标识符d确定的类型。通过使用新发明的类型模板参数P替换auto的出现次数,或者如果初始化程序是 braced-init-list ,则从T获取U (8.5.4),std::initializer_list<U>从变量d推导出的类型是使用函数调用(14.8.2.1)中的模板参数推导规则确定的推导A,其中P是函数模板参数类型和d的初始化程序是相应的参数。如果扣除失败,则声明格式不正确。

     

[C++11: 14.8.2.1/3]: 如果P是cv限定类型,则P类型的顶级cv限定符将被忽略以进行类型推导。如果P是引用类型,P引用的类型将用于类型推导。如果P是对cv-nonqualified模板参数的右值引用,则参数是左值,类型“A的左值参考”用于代替A进行类型扣除。

您已经添加了&(即使std::map<int, int>::find const要返回引用也是必需的,顺便说一句,这不是必需的);现在添加const(按上述要求)!

答案 1 :(得分:0)

您的错误原因是尝试将临时对象绑定到非const的左值引用。

考虑这个例子:

      int  i = 42;
const int ci = 42;

auto& a =  i; // type of  i is       int, value category of  i is lvalue -- OK
auto& b = ci; // type of ci is const int, value category of ci is lvalue -- OK
auto& c = 42; // type of 42 is       int, value category of 42 is rvalue -- error

auto会根据模板广告扣除规则推断出初始化表达式的类型,因此aint&,b为const int&

但是如果初始化表达式是非const rvalue,如文字42ints.find(0)auto将推导出非const类型,那么cint&(对非const的左值引用),它不会绑定到右值。

auto&& d =  i; // d is       int&  -- OK
auto&& e = ci; // e is const int&  -- OK
auto&& f = 42; // f is       int&& -- OK

auto&&是一个转发引用,它将推导出初始化表达式的cv-qualification(constness)和value类别。