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

why auto i = same_const_variable could not deduce "const"?

const int ci = 10;
auto i = ci;  // i will be "int" instead of "const int"
i = 20;

我想知道为什么 auto 是为这种行为设计的?

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

这里有什么问题?

我认为理解为什么会帮助我们记住它

auto 主要遵循与模板参数推导相同的类型推导规则。唯一的区别是 auto 在某些情况下会从 braced-init-list 推导 std::initializer_list,而模板参数推导不会这样做。

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

6   ... The type deduced for the variable d is then the deduced A determined using the rules of template argument deduction from a function call (14.8.2.1), ...

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

§14.8.2.1 [temp.deduct.call]

2   If P is not a reference type:
    — ...
    — If A is a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction.

因此,在

auto i = ci;

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

写的时候

auto& i = ci;

那么 i 不再是引用类型,上述规则不适用,因此保留 const 限定符。

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

auto i = 3,
     j = i,
     k = ci,
     m = 3 + 4; // All these variables are type int.

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

const auto i = 3;

自 C++14 起,还有 decltype(auto) 说明符将 decltype 应用于初始值设定项,以制作给定变量的副本。也许这真的是您所期望的:

decltype(auto) i = ci; // i receives type const int.

Live demo.

decltype(auto) 虽然有点棘手,但除了与确定 return 类型的函数调用包装器相关的最初目的外,它几乎没有用例。除非有充分的理由,否则请选择 const autoconst int

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

auto && i = ci; // i receives type const int & and aliases ci.

这没有那么表达和具体,但可靠地将 i 声明为 ci 的别名。您尝试的另一件事是 auto &,它类似但只允许形成对预先存在的变量的引用。

auto & i = ci; // i receives type const int & and aliases ci.

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