C++ 根据规范,const引用是否需要auto的const?
编辑我错过了一个重要的细节,地图是C++ 根据规范,const引用是否需要auto的const?,c++,c++11,C++,C++11,编辑我错过了一个重要的细节,地图是const。该示例已更新 考虑 const std::map<int, int> ints; auto& it = ints.find(0); const std::map ints; 自动&it=ints.find(0); 复习C++(工作草案)规范以及Stroustrup的《C++编程语言,第四版》,我不能确定是否需要 const >(我相信用 const 明确地修饰类型是更好的风格,但这不是我的问题)。Visual Studio
const
。该示例已更新
考虑
const std::map<int, int> ints;
auto& it = ints.find(0);
const std::map ints;
自动&it=ints.find(0);
复习C++(工作草案)规范以及Stroustrup的《C++编程语言,第四版》,我不能确定是否需要<代码> const >(我相信用<代码> const <代码>明确地修饰类型是更好的风格,但这不是我的问题)。Visual Studio 2013将其编译得很好,推导出const
我理解,裸自动
(即没有装饰,如常量
或&
)将推断出非常量、非引用类型
在Stroupstrup书中的每一个例子中,他都使用const auto&
和neverauto&
来处理这样的场景编辑但他没有提到使用常量
的选项/需要,它们只是自动
的示例
gcc 4.9.1未能编译,mac的xcode也未能编译:
错误:初始化类型为…的非常量引用无效。
这些是编译器选项吗?规范对此是否有任何说明
谢谢。是的,这种行为完全是标准的:
[C++11:7.1.6.4/5]:
在本节未明确允许的上下文中使用auto
的程序是格式错误的
[C++11:7.1.6.4/6]:
根据8.3确定声明器id的类型后,使用声明器id的声明变量的类型将使用模板参数推断规则从其初始值设定项的类型确定。让T
为变量标识符d确定的类型。从T
获取P
,方法是使用新发明的类型模板参数U
替换出现的auto,或者如果初始值设定项是带括号的初始列表(8.5.4),则使用std::initializer\U list
替换出现的auto为变量d
推导的类型是使用函数调用(14.8.2.1)的模板参数推导规则确定的推导A
,其中P
是函数模板参数类型,d
的初始值设定项是相应的参数。如果扣除失败,则声明格式错误。
[C++11:14.8.2.1/3]:
如果p
是cv限定类型,则在类型推断时忽略p
类型的顶级cv限定符。如果P
是引用类型,则使用P
引用的类型进行类型推断。如果P
是对cv非限定模板参数的右值引用,且参数是左值,则使用类型“对a
的左值引用”代替a
进行类型推断
您已经添加了
&
(即使std::map::find 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
将根据模板a分段推断规则推断初始化表达式的类型,因此a
是int&
,b是const int&
但是,如果初始化表达式是一个非常量值,如literal42
或ints.find(0)
,auto
将推导出一个非常量类型,因此c
是一个不会绑定到RVA值的int&
(对非常量的左值引用)
auto&& d = i; // d is int& -- OK
auto&& e = ci; // e is const int& -- OK
auto&& f = 42; // f is int&& -- OK
auto&&
是一个转发引用,它将推导其初始化表达式的cv限定(contness)和值类别。auto
使用模板参数推导规则,其推导内容完全由标准指定<代码>自动&不会推断常量限定类型,除非您尝试将其绑定到常量限定对象。哦,天哪,现在这是一个完全不同的问题。以后请多加小心,我还是不明白。。。为什么map
在这里是const
还是不重要?这会影响map::find
的返回类型,如果map
是const
,则返回map::iterator
,否则在这两种情况下都会按值返回map::iterator
。因此,无论映射的常量是多少,上面的代码都无法编译,因为您试图将右值绑定到非常量左值引用。VS编译它是因为非标准扩展;如果使用/W4