在 C++ 中限制 "auto" 不会破坏它的目的吗?
Doesn't constraining the "auto" in C++ defeat the purpose of it?
在 C++20 中,我们现在可以将 auto
关键字限制为仅属于特定类型。所以如果我有一些代码看起来像下面没有任何限制:
auto something(){
return 1;
}
int main(){
const auto x = something();
return x;
}
这里的变量x
被推导为一个int
。但是,随着 C++20 的引入,我们现在可以将 auto
限制为某种类型,如下所示:
std::integral auto something(){
return 0;
}
int main(){
const auto x = something();
return x;
}
这不是违背auto
的目的吗?如果我真的需要 std::integral
数据类型,难道我不能完全省略 auto
吗?我是否完全误解了 auto
的用法?
对推导的 auto
类型的约束并不意味着它需要是 特定的 类型,这意味着它需要是 set 满足约束的类型。请注意,约束和类型不是一回事,它们不可互换。
例如像 std::integral 这样的概念将推导类型限制为整数类型,例如 int
或 long
,但不是 float
或 std::string
.
If I really need a std::integral
datatype, couldn't I just omit the auto
completely?
原则上,我想你可以,但这至少会导致解析困难。例如在像
这样的声明中
foo f = // ...
是foo
类型,还是对类型的约束?
而在当前语法中,我们有
foo auto f = // ...
毫无疑问 foo
是对 f
.
类型的约束
If I really need a std::integral
datatype, couldn't I just omit the auto completely?
不,因为 std::integral
is not a type, it's a concept,类型约束(或者,如果您愿意,一组类型而不是单一类型)。
Doesn't this defeat the purpose of auto here?
C++11 中 auto
的最初目的是告诉编译器:无论你推导出什么类型。*
对于 C++20,auto
有一个扩展的用例 - 以及一个概念,即对类型的约束。 auto
仍然 告诉编译器:无论你推导什么类型 - 但推导也必须遵守约束。
* - 忽略常量、l/rvalue 引用等问题
一个概念通常只是将错误移到编译的较早位置,并使代码更具可读性(因为概念名称是对 reader 您对类型的要求的提示)。
改写:
您很少会以适用于所有类型的方式使用自动变量。
例如:
auto fn(auto x) {
return x++;
}
如果你这样做将不起作用:
f(std::string("hello"));
因为你不能增加 std::string
,错误是这样的:
error: cannot increment value of type 'std::basic_string<char>'
return x++;
如果将函数更改为:
auto fn(std::integral auto x) {
return x++;
}
您将收到如下错误:
:6:6: note: candidate template ignored: constraints not
satisfied [with x:auto = std::basic_string] auto
fn(std::integral auto x) {
对于一个小例子来说,这并不重要,但对于实际代码来说,fn 经常会调用 fn2,然后调用 fn3...你会在 std/boost/ 中得到错误。 .. 实现文件。
因此概念以这种方式将错误移至第一个函数调用的位置。
在 C++20 中,我们现在可以将 auto
关键字限制为仅属于特定类型。所以如果我有一些代码看起来像下面没有任何限制:
auto something(){
return 1;
}
int main(){
const auto x = something();
return x;
}
这里的变量x
被推导为一个int
。但是,随着 C++20 的引入,我们现在可以将 auto
限制为某种类型,如下所示:
std::integral auto something(){
return 0;
}
int main(){
const auto x = something();
return x;
}
这不是违背auto
的目的吗?如果我真的需要 std::integral
数据类型,难道我不能完全省略 auto
吗?我是否完全误解了 auto
的用法?
对推导的 auto
类型的约束并不意味着它需要是 特定的 类型,这意味着它需要是 set 满足约束的类型。请注意,约束和类型不是一回事,它们不可互换。
例如像 std::integral 这样的概念将推导类型限制为整数类型,例如 int
或 long
,但不是 float
或 std::string
.
If I really need a
std::integral
datatype, couldn't I just omit theauto
completely?
原则上,我想你可以,但这至少会导致解析困难。例如在像
这样的声明中foo f = // ...
是foo
类型,还是对类型的约束?
而在当前语法中,我们有
foo auto f = // ...
毫无疑问 foo
是对 f
.
If I really need a
std::integral
datatype, couldn't I just omit the auto completely?
不,因为 std::integral
is not a type, it's a concept,类型约束(或者,如果您愿意,一组类型而不是单一类型)。
Doesn't this defeat the purpose of auto here?
C++11 中 auto
的最初目的是告诉编译器:无论你推导出什么类型。*
对于 C++20,auto
有一个扩展的用例 - 以及一个概念,即对类型的约束。 auto
仍然 告诉编译器:无论你推导什么类型 - 但推导也必须遵守约束。
* - 忽略常量、l/rvalue 引用等问题
一个概念通常只是将错误移到编译的较早位置,并使代码更具可读性(因为概念名称是对 reader 您对类型的要求的提示)。
改写:
您很少会以适用于所有类型的方式使用自动变量。
例如:
auto fn(auto x) {
return x++;
}
如果你这样做将不起作用:
f(std::string("hello"));
因为你不能增加 std::string
,错误是这样的:
error: cannot increment value of type 'std::basic_string<char>'
return x++;
如果将函数更改为:
auto fn(std::integral auto x) {
return x++;
}
您将收到如下错误:
:6:6: note: candidate template ignored: constraints not satisfied [with x:auto = std::basic_string] auto fn(std::integral auto x) {
对于一个小例子来说,这并不重要,但对于实际代码来说,fn 经常会调用 fn2,然后调用 fn3...你会在 std/boost/ 中得到错误。 .. 实现文件。
因此概念以这种方式将错误移至第一个函数调用的位置。