const auto & 和 auto & if reference 对象之间的区别是 const
Difference between const auto & and auto & if object of reference is const
// case 1
const int i = 42;
const auto &k = i;
// case 2
const int i = 42;
auto &k = i;
在这种情况下,我们是否需要在auto
之前使用const
关键字?毕竟,对自动推导类型的引用(k
(将包括对象的顶层const
(const
int 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
性与变量i
的const
性耦合。我想既然这个问题的标题是">const auto & and auto & ...之间的区别",那么在这里强调实用性差异很重要,如果你不输入 theconst
关键字,你就不能保证参考文献将具有此简历资格。在某些需要这样做的情况下,为什么要让i
在未来保持const
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- 为什么 const auto &p{nullptr} 在 C++17 中不起作用,而 auto *p{nullptr} 不起作用?
- const auto & 和 auto & if reference 对象之间的区别是 const
- 为什么"const auto [x, y]"绑定到引用类型时没有按预期运行?
- 用 decltype 和 auto 推导出 const(返回)类型
- 避免使用 auto 关键字从字面上复制 const 和非 const 的代码?
- 将右值分配给'const auto&'时会发生什么情况
- 为什么在auto和template函数的情况下,类型都没有推导为"const"类型
- auto&x = const int *的类型是什么?
- 将 const auto & 转换为迭代器
- 返回指向 const 数据成员和 'auto' 关键字的 const 指针。有点困惑
- 为什么"auto"将字符串声明为 const char* 而不是 std::string?
- 'const auto'的间接级别与'const char *const '不同
- 如何在STLport库中使用const auto
- auto and const object
- 在 for-each 循环中使用 'auto' 时是否需要添加'const'?
- C++ : const int * 和 cont int & 之间的 auto 类型不同的扣除
- 返回const auto对象——和Qt隐式共享
- const auto std::initializer_list Clang与GCC的差异
- const auto会导致编译器崩溃