在 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 这样的概念将推导类型限制为整数类型,例如 intlong,但不是 floatstd::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/ 中得到错误。 .. 实现文件。

因此概念以这种方式将错误移至第一个函数调用的位置。