Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 根据规范,const引用是否需要auto的const?_C++_C++11 - Fatal编程技术网

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&
和never
auto&
来处理这样的场景编辑但他没有提到使用
常量
的选项/需要,它们只是
自动
的示例

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&

但是,如果初始化表达式是一个非常量值,如literal
42
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