为什么auto i = same_const_variable无法推断出"const"?

cam*_*ino 3 c++ auto c++11 type-deduction

const int ci = 10;
auto i = ci;  // i will be "int" instead of "const int"
i = 20;
Run Code Online (Sandbox Code Playgroud)

我想知道为什么汽车是为这种行为而设计的?

为什么类型i是"int"而不是"const int"?

这里有什么问题?

我想明白为什么会帮助我们记住它

Pra*_*ian 6

auto大多数遵循相同类型的扣除规则作为模板参数推导.唯一的区别是在某些情况下autostd::initializer_listbraced-init-list推导出来,而模板参数推断不会这样做.

来自N3337,§7.1.6.4[dcl.spec.auto]

6 ... d然后A使用函数调用(14.8.2.1)中的模板参数推导规则确定推导出的变量类型,...

您正在观察的行为与从函数调用中推导出类型时的模板参数推导相同

§14.8.2.1[temp.deduct.call]

2如果P不是引用类型:
    - ...
    - 如果A是cv限定类型,A类型扣除将忽略类型的顶级cv限定符.

因此,在

auto i = ci;
Run Code Online (Sandbox Code Playgroud)

顶级const限定符被忽略并i推断为int.

当你写作

auto& i = ci;
Run Code Online (Sandbox Code Playgroud)

然后i不再是引用类型,并且上述规则不适用,因此const保留限定符.

  • @camino你正在制作一份新的副本.为什么原件的CV资格会影响副本的资格? (9认同)
  • @curiousguy不是真的.在答案中已经解决问题之后,在评论中发出的链式派生问题是一个问题.真正发生的原因是它基于模板类型推导.为什么模板类型推导确实是一个相关但不同的问题. (2认同)

Pot*_*ter 5

auto本身意味着您需要一个新的、本地拥有的变量,其中包含给定值的副本。const-ness 不是价值的一部分。Anintint使用文字、命名常量、表达式还是非const变量指定的。

auto i = 3,
     j = i,
     k = ci,
     m = 3 + 4; // All these variables are type int.
Run Code Online (Sandbox Code Playgroud)

要获得推导类型的常量,您仍然可以使用auto const. 这在声明中表达了如何使用变量。

const auto i = 3;
Run Code Online (Sandbox Code Playgroud)

从 C++14 开始,还有decltype(auto)适用decltype于初始化程序的说明符,用于制作给定变量的副本。也许这真的是你所期望的:

decltype(auto) i = ci; // i receives type const int.
Run Code Online (Sandbox Code Playgroud)

现场演示

decltype(auto)不过,这有点棘手,除了与决定函数调用包装器的返回类型有关的最初目的之外,它几乎没有用例。除非有充分的理由,否则选择const autoconst int代替。

另一种选择是使用转发引用,拼写auto &&。这指的是初始化它的变量或值,无论它是什么。

auto && i = ci; // i receives type const int & and aliases ci.
Run Code Online (Sandbox Code Playgroud)

这不太具有表现力和具体性,但可靠地声明ici. 您尝试的另一件事是auto &,它是类似的,但只允许形成对预先存在的变量的引用。

auto & i = ci; // i receives type const int & and aliases ci.
Run Code Online (Sandbox Code Playgroud)

const int变量的引用必须是 类型const int &,否则将允许非法修改。

  • @curiousguy `decltype(x)` 与 `decltype((x))` 不同。这是一个令人憎恶的*而且*它很棘手。但是,它的行为与问题中暗示的期望相同。 (4认同)