与 C++23 结合推导具有自动返回类型的 this 和转换运算符?

康桓瑋*_*康桓瑋 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 Sthis 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

[class.conv.fct]p9

转换函数模板不应具有推导的返回类型。

operator auto(this auto)是一个缩写的函数模板,因此它无效。

它被禁止的原因是它在当时的用途有限,而且我认为 GCC 在命名这个函数时遇到了非常困难的时期(另请参阅:CWG1670

您会看到类似的行为:

template<int = 0>
operator auto() { return 42; }
Run Code Online (Sandbox Code Playgroud)