const auto & 和 auto & 之间的区别,如果引用对象是 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
) 的整数的引用。
如果这是真的,那是否意味着情况 1 中的 const auto &k = i;
被编译器替换为 const int &k = i;
(auto
被替换为 int
)?而在情况 2 中,auto
被替换为 const int
?
在第一种情况下略有不同 auto
将推导为 const int
,在第二种情况下将推导为 int
(正如您明确说明的 const)。
The keyword auto may be accompanied by modifiers, such as const or &, which will participate in the type deduction. For example, given const auto& i = expr;, the type of i is exactly the type of the argument u in an imaginary template template void f(const U& u) if the function call f(expr) was compiled. Therefore, auto&& may be deduced either as an lvalue reference or rvalue reference according to the initializer, which is used in range-based for loop.
所以对你来说这意味着
// case 1
const int i = 42;
const auto &k = i; // auto -> int
// case 2
const int i = 42;
auto &k = i; // auto -> const int
但是,在我看来,更重要的是,如果您明确声明 const 并保证常量,则意图会更清楚。因此,在这种情况下,我显然更喜欢它。
auto
关键字在编译时自动决定变量的类型。
在第一种情况下,auto
减少为 int
,在第二种情况下减少为 const int
。因此,您的两种情况都减少为与以下代码相同的代码:
const int &k = i;
但是,为了更好的可读性并确保您的变量 TRULY 是 const
.
,最好显式地使用 const
使用 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
修改,第二种情况不可以
接受的答案是正确的,即编译结果没有区别。需要注意的重要一点是 auto&
版本是 耦合 const
参考 k
与 const
-变量的内在性 i
。我想既然问题的标题是“const auto & 和 auto & ... 之间的区别”,那么强调这里的实用差异很重要,如果你不把const
关键字,你不能保证引用会有这个 cv-qualification。在某些需要这样做的情况下,为什么要让 i
有机会在未来保持 const
?
您好,欢迎来到 stack overflow。
正如这个小测试程序所示,无论您如何指定 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 值的衰减。
// 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
) 的整数的引用。
如果这是真的,那是否意味着情况 1 中的 const auto &k = i;
被编译器替换为 const int &k = i;
(auto
被替换为 int
)?而在情况 2 中,auto
被替换为 const int
?
在第一种情况下略有不同 auto
将推导为 const int
,在第二种情况下将推导为 int
(正如您明确说明的 const)。
The keyword auto may be accompanied by modifiers, such as const or &, which will participate in the type deduction. For example, given const auto& i = expr;, the type of i is exactly the type of the argument u in an imaginary template template void f(const U& u) if the function call f(expr) was compiled. Therefore, auto&& may be deduced either as an lvalue reference or rvalue reference according to the initializer, which is used in range-based for loop.
所以对你来说这意味着
// case 1
const int i = 42;
const auto &k = i; // auto -> int
// case 2
const int i = 42;
auto &k = i; // auto -> const int
但是,在我看来,更重要的是,如果您明确声明 const 并保证常量,则意图会更清楚。因此,在这种情况下,我显然更喜欢它。
auto
关键字在编译时自动决定变量的类型。
在第一种情况下,auto
减少为 int
,在第二种情况下减少为 const int
。因此,您的两种情况都减少为与以下代码相同的代码:
const int &k = i;
但是,为了更好的可读性并确保您的变量 TRULY 是 const
.
使用 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
修改,第二种情况不可以
接受的答案是正确的,即编译结果没有区别。需要注意的重要一点是 auto&
版本是 耦合 const
参考 k
与 const
-变量的内在性 i
。我想既然问题的标题是“const auto & 和 auto & ... 之间的区别”,那么强调这里的实用差异很重要,如果你不把const
关键字,你不能保证引用会有这个 cv-qualification。在某些需要这样做的情况下,为什么要让 i
有机会在未来保持 const
?
您好,欢迎来到 stack overflow。
正如这个小测试程序所示,无论您如何指定 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 值的衰减。