C++20 中概念化的“operator auto”

时间:2021-07-30 21:13:58

标签: c++ c++20 auto c++-concepts

从 C++20 开始,我们可以在 auto 关键字之前加上概念的名称来限制可能的类型。特别是这种组合在类转换operator auto中是可能的,例如

template <typename T> concept x = true;

struct S
{
    operator x auto() { return 2; }
    operator auto() { return 1; }
};

int main() { return S{}.operator x auto(); }

但是 Clang 是唯一接受整个程序的编译器,但是 main() 返回 1(而不是我预期的 2),演示:https://gcc.godbolt.org/z/b16jYGa81

GCC 接受结构体定义,但拒绝编译 S{}.operator x auto()

并且 MSVC 拒绝接受甚至 struct S 的错误:

error C2535: 'S::operator auto(void)': member function already defined or declared

只是想知道,哪个编译器就在这里(如果有的话)?

1 个答案:

答案 0 :(得分:20)

这个转换函数:

operator auto() { return 1; }

意思和这个转换函数完全一样:

operator int() { return 1; }

我们从 1 推导出返回类型,这不是函数模板。


这个转换函数:

operator x auto() { return 2; }

意思大致相同:

operator int() { static_assert(x<int>); return 2; }

我们从 2 推导出返回类型,并确保该类型 (int) 满足特定概念 (x)。


将两者放在一起,我们有两个函数(都不是函数模板),它们都被命名为operator int(),这是不允许的。即使在声明时,这也应该是格式错误的,因为名称 operator int() 绑定到两个相互冲突的声明。

请注意,第二个仍然命名为 operator int(),而不是 operator x auto()