从 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
只是想知道,哪个编译器就在这里(如果有的话)?
答案 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()
。