自动类型演绎中的Const

时间:2015-08-07 08:26:53

标签: c++ c++11 reference auto effective-c++

我正在阅读Scott Meyers的有效现代C ++。第1项包含以下示例:

template<typename T>
void f(T& param);       // param is a reference
int x = 27;             // x is an int
const int cx = x;       // cx is a const int
f(cx);                  // T is const int,
                        // param's type is const int&

在第3项中出现以下示例:

Widget w;
const Widget& cw = w;
auto myWidget1 = cw;             // auto type deduction:
                                 // myWidget1's type is Widget

根据第1项,我预计myWidget1的类型为const Widget。我错过了什么吗?

2 个答案:

答案 0 :(得分:3)

在大多数情况下,auto遵循模板参数推导的规则:

§7.1.6.4[dcl.spec.auto] / p6:

  

根据8.3确定 declarator-id 的类型后,声明的变量的类型   使用 declarator-id 是使用模板参数规则从其初始化程序的类型确定的   扣除。设T为已为变量标识符d确定的类型。从P获取T   使用新发明的类型模板参数auto替换U的出现次数,或者,如果初始化程序   是 braced-init-list (8.5.4),std::initializer_list<U>。根据函数调用(14.8.2.1)中使用模板参数推导的规则确定推导出的变量d的类型{/ 1}}。

§14.8.2.1[temp.deduct.call] / p2:

  

如果A不是参考类型:

     
      
  • [...]

  •   
  • 如果P是cv限定类型,则类型扣除会忽略A类型的顶级cv限定符。

  •   

如果您希望A属于myWidget1类型,则应将其声明为引用类型,例如:

const Widget&

DEMO

答案 1 :(得分:1)

auto myWidget1 = cw;遵循Meyers书中模板参数类型推导的第三条规则,即按值传递。 当你按值传递时,cv-qualifiers和references会被忽略,因为你得到了一个对象的新副本,所以你并不关心你复制的旧对象是const还是引用。