有什么方法可以在没有前向声明的情况下将朋友从模板导出到全局命名空间?
template <typename T>
struct flags {
static_assert(std::is_enum_v<T>);
using base = std::underlying_type_t<T>;
friend T operator|(const T lhs, const T rhs) {
return T(base(lhs) | base(rhs));
}
};
enum class MyEnum {
A,
B
};
template struct flags<MyEnum>;
auto operator|(MyEnum, MyEnum) -> MyEnum; // (1)
MyEnum myEnum = MyEnum::A | MyEnum::B; //Not compile without (1)
Run Code Online (Sandbox Code Playgroud)
首先让我说这是一个很好的和富有想象力的代码生成想法。但是没有办法公开用于参数相关查找的友元函数。
问题是 ADL 只考虑关联命名空间和类类型的朋友。对于与类类型相关联的枚举,它必须是类的成员,即特化的成员flags。否则无法将枚举与类类型(用于 ADL 目的)相关联。
在您的用例中,枚举显然不打算成为 的成员flags<MyEnum>,因此flags<MyEnum>在只涉及MyEnum.