什么是 C++ 中的“运算符自动”?

What is 'operator auto' in C++?

提问人:Fedor 提问时间:7/6/2021 最后编辑:Fedor 更新时间:7/14/2021 访问量:6335

问:

Clang 和 Visual Studio 编译器(但不是 GCC)允许按如下方式编写代码:

struct A
{
  operator auto() { return 0; }
};

int main()
{
   A a;
   a.operator auto();
}

什么?它是特定编译器的扩展还是标准语言功能,如果是,它出现在哪种语言标准(例如 C++17)中?operator auto

C++ 运算符关键字

评论

1赞 Toby Speight 7/7/2021
虽然你不能像 GCC 那样直接调用它,但它会接受 or .x = a;x = a.operator int();
1赞 αλεχολυτ 7/9/2021
顺便说一句,多个.operator auto

答:

27赞 songyuanyao 7/6/2021 #1

当用于用户定义的转换函数时,类型将通过返回类型推导来推导,即 对于这种情况 ()。这是在 C++14 中引入的。autoint0

占位符 auto 可以在 conversion-type-id 中使用,表示推断出的返回类型

struct X {
    operator int(); // OK
    operator auto() -> short;  // error: trailing return type not part of syntax
    operator auto() const { return 10; } // OK: deduced return type
};

评论

1赞 Benjamin Bihler 7/6/2021
G++ 10.2 打印。为什么?error: 'struct A' has no member named 'operator auto'
9赞 HTNW 7/6/2021
这回答了问题的主要部分,但最有趣的部分仍然是:标准对此功能的“名称”有什么看法?Clang 和 VS 认为有效和无效是正确的,还是 GCC(相反)是对的?该标准是否对声明两个 s 有任何规定(例如,所有编译器都拒绝)?a.operator auto()a.operator int()operator autooperator auto() { return 0; } operator auto() { return 0.0; }
1赞 songyuanyao 7/6/2021
Gcc 似乎是对的(对我来说);@eerorika发布了一个关于它的问题
6赞 Enlico 7/6/2021 #2

它是标准的,来自 C++14,正如你在这里看到的。

简而言之,这意味着返回类型是根据 return 语句通过类型推导确定的。

换言之,以下代码段中的三个 s 触发了相同类型的推导机制auto

struct A
{
  auto operator()() { return 0; } // auto is the return type
  auto some_fun() { return 0; }   // auto is the return type
  operator auto() { return 0; }   // auto is not the return type
                                  // but it's deduced in the same way
};

因此,您对其他具有返回类型的函数所期望的所有要求/限制也适用于此处,例如,如果存在多个 return 语句,它们应导致推断出相同的类型,依此类推。auto

27赞 eerorika 7/6/2021 #3

什么是 C++ 中的运算符自动?

operator auto() { return 0; }

operator T是 类型的转换运算符。 是将要推导的占位符类型的关键字。当用作返回类型时,将从 return 语句中扣除该类型。Tauto

在这种情况下,将被推导出为 ,因此它是 的隐式转换运算符。它允许您编写例如:autointint

A a;
int i = a;

它出现在什么语言标准(例如C++17)中?

转换运算符至少从第一个标准版本开始就已经使用该语言。 返回类型是在 C++14 中引入的。auto


a.operator auto();

编译器似乎不同意如何显式调用运算符:

a.operator auto(); // Clang: OK,    GCC: ERROR
a.operator int();  // Clang: ERROR, GCC: OK

这在语言中可能未说明。

我认为没有理由做这样的电话,你可以用它来代替,所以我建议避免它。或者,如果您更喜欢使用调用语法,则不要使用 .static_castauto

评论

4赞 eerorika 7/6/2021
我创建了一个关于调用语法的后续问题:stackoverflow.com/q/68267176/2079303
1赞 Gian Paolo 7/7/2021
这在语言中可能被低估了 c++ 可能是历史上更指定的语言,标准是数百页(如果不是数千页,我不知道)页。然而,总有空间容纳一些未被遗漏的东西。不是抱怨,只是事实问题;标准是一件好事,但也是一件永远不可能完美的事情