C++20 中概念化的“operator auto”
Conceptualized `operator auto` in C++20
从 C++20 开始,我们可以在 auto
关键字之前加上概念的名称来限制可能的类型。特别是这种组合在 class 转换 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()
returns 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
想知道这里是哪个编译器(如果有的话)?
这个转换函数:
operator auto() { return 1; }
意思和这个转换函数完全一样:
operator int() { return 1; }
我们从 1
推导出 return 类型,这不是函数模板。
这个转换函数:
operator x auto() { return 2; }
意思大致相同:
operator int() { static_assert(x<int>); return 2; }
我们从 2
推导出 return 类型并确保该类型 (int
) 满足特定概念 (x
)。
将两者放在一起,我们有两个 函数 (都不是函数模板),它们都被命名为 operator int()
,这是不允许的。即使在声明点这也应该是错误的,因为名称 operator int()
绑定到两个相互冲突的声明。
请注意,第二个仍命名为 operator int()
,而不是 operator x auto()
。
从 C++20 开始,我们可以在 auto
关键字之前加上概念的名称来限制可能的类型。特别是这种组合在 class 转换 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()
returns 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
想知道这里是哪个编译器(如果有的话)?
这个转换函数:
operator auto() { return 1; }
意思和这个转换函数完全一样:
operator int() { return 1; }
我们从 1
推导出 return 类型,这不是函数模板。
这个转换函数:
operator x auto() { return 2; }
意思大致相同:
operator int() { static_assert(x<int>); return 2; }
我们从 2
推导出 return 类型并确保该类型 (int
) 满足特定概念 (x
)。
将两者放在一起,我们有两个 函数 (都不是函数模板),它们都被命名为 operator int()
,这是不允许的。即使在声明点这也应该是错误的,因为名称 operator int()
绑定到两个相互冲突的声明。
请注意,第二个仍命名为 operator int()
,而不是 operator x auto()
。