bee*_*oop 72 c++ auto c++-concepts c++20
在 C++20 中,我们现在能够将auto关键字限制为仅属于特定类型。因此,如果我有一些如下所示的代码,没有任何限制:
auto something(){
return 1;
}
int main(){
const auto x = something();
return x;
}
Run Code Online (Sandbox Code Playgroud)
这里的变量x被推导为一个int。然而,随着 C++20 的引入,我们现在可以将 约束auto为某种类型,如下所示:
std::integral auto something(){
return 0;
}
int main(){
const auto x = something();
return x;
}
Run Code Online (Sandbox Code Playgroud)
这不是违背了来这里的目的吗auto?如果我真的需要一个std::integral数据类型,我不能完全省略吗auto?我是否完全误解了使用auto?
cig*_*ien 79
对推导类型的约束auto并不意味着它需要是特定类型,而是意味着它需要是满足约束的一组类型之一。请注意,约束和类型不是同一件事,并且它们不可互换。
例如,像std::integral 这样的概念将推导类型限制为整数类型,例如intor long,但不是float, or std::string。
如果我真的需要一个
std::integral数据类型,我不能完全省略吗auto?
原则上,我想你可以,但这至少会导致解析困难。例如在声明中
foo f = // ...
Run Code Online (Sandbox Code Playgroud)
是foo类型,还是类型的约束?
而在当前语法中,我们有
foo auto f = // ...
Run Code Online (Sandbox Code Playgroud)
毫无疑问,这foo是对 的类型的限制f。
ein*_*ica 37
如果我真的需要一种
std::integral数据类型,我不能完全省略 auto 吗?
不,因为std::integral它不是一种类型,而是一个概念,是对类型的约束(或者如果你愿意的话,是一组类型而不是单个类型)。
这不是违背了 auto 的目的吗?
C++11 中的最初目的auto是告诉编译器:无论你推导出什么类型。*
对于 C++20,auto有一个扩展的用例 - 以及一个概念,对类型的约束。auto 仍然告诉编译器:无论你推导出什么类型- 但推导也必须遵守约束。
* - 忽略常量、左/右值引用等问题。
概念通常只是将错误移到编译的早期,并使代码更具可读性(因为概念名称是向读者提示您对类型的要求)。
改写:
您很少会以适用于每种类型的方式使用自动变量。
例如:
auto fn(auto x) {
return x++;
}
Run Code Online (Sandbox Code Playgroud)
如果你这样做,将不起作用:
f(std::string("hello"));
Run Code Online (Sandbox Code Playgroud)
因为您无法递增std::string,所以错误类似于:
error: cannot increment value of type 'std::basic_string<char>'
return x++;
Run Code Online (Sandbox Code Playgroud)
如果将函数更改为:
auto fn(std::integral auto x) {
return x++;
}
Run Code Online (Sandbox Code Playgroud)
你会得到类似这样的错误:
:6:6: 注意:候选模板被忽略:不满足约束[with x:auto = std::basic_string] auto fn(std::integral auto x) {
对于一个小例子来说,这并不重要,但对于实际代码,通常 fn 会调用 fn2 调用 fn3... 并且您会在 std/boost/... 实现文件深处得到错误。
因此,通过这种方式,概念将错误转移到第一个函数调用的位置。