康桓瑋*_*康桓瑋 16 c++ language-lawyer type-deduction c++23 explicit-object-parameter
我最近注意到一个关于 C++23推导此功能的奇怪问题。
S假设我们有一个带有简单转换运算符的结构:
struct S {
operator int() { return 42; }
};
int i = S{};
Run Code Online (Sandbox Code Playgroud)
由于42是 类型int,我们可以将转换运算符的返回类型指定为auto,例如:
struct S {
operator auto() { return 42; }
};
int i = S{};
Run Code Online (Sandbox Code Playgroud)
这完全没问题。如果我们应用C++23来推导它的这个特性,那就是:
struct S {
operator auto(this S) { return 42; }
};
int i = S{};
Run Code Online (Sandbox Code Playgroud)
这也完全没问题。但是,当我替换this S为this auto:
struct S {
operator auto(this auto) { return 42; }
};
int i = S{};
Run Code Online (Sandbox Code Playgroud)
所有三个编译器都拒绝上述代码。海湾合作委员会给出:
<source>:5:9: error: cannot convert 'S' to 'int' in initialization
5 | int i = S{};
Run Code Online (Sandbox Code Playgroud)
但是,当我将转换运算符的返回类型更改回 时int,所有三个编译器都可以正常编译:
struct S {
operator int(this auto) { return 42; }
};
int i = S{};
Run Code Online (Sandbox Code Playgroud)
这让我很困惑。
为什么编译器会拒绝operator auto(this auto) { return 42; }?我认为没有理由拒绝它,因为它对我来说似乎很直观。所以我想知道标准对此有何规定?或者这是一个编译器错误?
Art*_*yer 17
这是CWG1878。
转换函数模板不应具有推导的返回类型。
operator auto(this auto)是一个缩写的函数模板,因此它无效。
它被禁止的原因是它在当时的用途有限,而且我认为 GCC 在命名这个函数时遇到了非常困难的时期(另请参阅:CWG1670)
您会看到类似的行为:
template<int = 0>
operator auto() { return 42; }
Run Code Online (Sandbox Code Playgroud)