const auto & 和 auto & if reference 对象之间的区别是 const

Difference between const auto & and auto & if object of reference is const

本文关键字:auto const 之间 区别 reference if 对象      更新时间:2023-10-16
// case 1
const int i = 42;
const auto &k = i;
// case 2
const int i = 42;
auto &k = i;

在这种情况下,我们是否需要在auto之前使用const关键字?毕竟,对自动推导类型的引用(k(将包括对象的顶层const(constint i(。所以我相信k在这两种情况下都是对常量(const int &k(的整数的引用。

如果这是真的,这是否意味着const auto &k = i;在情况 1 中被编译器替换为const int &k = i;(auto被替换为int(?而在情况 2 中,auto替换为const int

auto关键字在编译时自动决定变量的类型。

在第一种情况下,auto减少到int在第二种情况下减少到const int。因此,您的两种情况都简化为与以下相同的代码:

const int &k = i;

但是,最好显式使用 const,以获得更好的可读性,并确保您的变量TRUEconst

具有auto的类型推导的工作方式类似于模板参数类型推导,但有一些例外情况不适用于给定的示例。因此

const int i = 42;
const auto& k1 = i; // same as const int& k1 = i;
auto& k2 = i; // same as (const int)& k2 = i;

尽管如此,添加const限定符可能更具可读性。

这是另一个例子,其中偏爱简洁与auto具有误导性:

int *i;
const auto k1 = i; // same as int* const k1 = i;
const auto *k2 = i;  // same as const int *k2 = i;

在第一种情况下,i指向的对象可以通过k1进行修改,在第二种情况下,它不能。

嗨,欢迎来到堆栈溢出。

正如这个小测试程序所示,无论您如何指定k的类型,编译器都不会让您失去i的恒定性。

#include <iostream>
#include <type_traits>
#include <string>
#define XSTR(s) STR(s)
#define STR(s) #s
template<class T> 
struct type;
template<>
struct type<int>
{
static std::string name() { return "int"; }
};
template<class T>
struct type<T&&>
{
static std::string name() { return type<T>::name() + " &&"; }
};
template<class T>
struct type<T&>
{
static std::string name() { return type<T>::name() + " &"; }
};
template<class T>
struct type<T const>
{
static std::string name() { return type<T>::name() + " const"; }
};
#define REPORT_CONST(decl, var, assign) 
{ 
decl var = assign; 
do_it(STR(decl var = assign;), var); 
}
template<class Var> 
void do_it(const char* message, Var&&)
{
std::cout << "case: " << message << " results in type: " << type<Var>::name() << 'n';
}
int main()
{
const int i = 42;
REPORT_CONST(const auto &, k, i);
REPORT_CONST(auto &, k, i);
REPORT_CONST(auto &&, k, std::move(i));
REPORT_CONST(auto const &&, k, std::move(i));
REPORT_CONST(int const&, k, i);
// REPORT_CONST(int &, k, i); // error: binding reference of type 'int&' to 'const int' discards qualifiers
}

预期成果:

case: const auto & k = i; results in type: int const &
case: auto & k = i; results in type: int const &
case: auto && k = std::move(i); results in type: int const &
case: auto const && k = std::move(i); results in type: int const &
case: int const& k = i; results in type: int const &

http://coliru.stacked-crooked.com/a/7c72c8ebcf42c351

另请注意命名 r 值衰减为 l 值。

在第一种情况下略有不同auto将推导出为const int,在第二种情况下推导出为int(正如您明确说明的常量(。

CPP 参考状态

关键字 auto 可能伴随着修饰符,例如 const 或 &,它们将参与类型推导。例如,给定 const auto&i = expr;,如果函数调用 f(expr( 被编译,则 i 的类型恰好是虚构模板模板 void f(const U& u( 中参数 u 的类型。因此,auto&&可以根据初始值设定项推导出为左值引用或右值引用,初始值设定项用于基于范围的 for 循环。

所以对你来说,这意味着

// case 1
const int i = 42;   
const auto &k = i;   // auto -> int
// case 2
const int i = 42;
auto &k = i;  // auto -> const int

然而,在我看来,更重要的是,如果你明确地陈述常量并保证恒定性,那么意图就会更清楚地陈述。因此,在这种情况下,我显然更喜欢它。

接受的答案是正确的,即编译结果没有区别。需要注意的是,auto&版本将k引用的const性与变量iconst耦合。我想既然这个问题的标题是">const auto & and auto & ...之间的区别",那么在这里强调实用性差异很重要,如果你不输入 theconst关键字,你就不能保证参考文献将具有此简历资格。在某些需要这样做的情况下,为什么要让i在未来保持const