什么是C++中的“operatorauto”?
Clang和 Visual Studio 编译器(但不是GCC)允许编写如下代码:
struct A
{
operator auto() { return 0; }
};
int main()
{
A a;
a.operator auto();
}
什么是operator auto?它是特定编译器的扩展还是标准语言功能,如果是,它是在什么语言标准(例如 C++17)中出现的?
回答
C++ 中的运算符 auto 是什么?
operator auto() { return 0; }
operator T是类型的转换运算符T。auto是将被推导的占位符类型的关键字。当用作返回类型时,类型将从返回语句中扣除。
在这种情况下,auto将被推导出为int,因此它是一个隐式转换运算符到int。它允许您编写例如:
A a;
int i = a;
它以什么语言标准(例如 C++17)出现?
至少从第一个标准版本开始,转换运算符就一直存在于该语言中。auto返回类型是在 C++14 中引入的。
a.operator auto();
编译器似乎不同意如何显式调用运算符:
a.operator auto(); // Clang: OK, GCC: ERROR
a.operator int(); // Clang: ERROR, GCC: OK
这可能在语言中未指定。
我不认为有理由进行这样的调用,因为你可以使用它static_cast来代替,所以我建议避免它。或者,如果您更喜欢使用调用语法,则不要使用auto.
- 我创建了一个关于调用语法的后续问题:/sf/ask/4778702351/
回答
当auto在用户定义的转换函数中使用时,类型将通过返回类型推导来推导,即int对于这种情况 ( 0)。这是在 C++14 中引入的。
占位符 auto 可用于convert-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 };
- 这回答了问题的主要部分,但最有趣的部分仍然是:标准对这个函数的“名称”的看法是什么?Clang 和 VS 认为 `a.operator auto()` 有效而 `a.operator int()` 无效,或者 GCC(相反)是否正确?标准是否说明了声明两个`operator auto`s(例如`operator auto() { return 0; } operator auto() { return 0.0; }`,所有编译器都拒绝)?
回答
它是标准的,来自 C++14,正如你在这里看到的。
简而言之,这意味着返回类型是根据 return 语句通过类型推导确定的。
换句话说,auto以下代码段中的三个s 触发了相同的类型推导机制
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
};
因此,您对具有auto返回类型的其他函数所期望的所有要求/限制也适用于此处,例如,如果存在多个 return 语句,它们应该导致推导出相同的类型,依此类推。