首页 > 解决方案 > 将朋友从模板导出到全局命名空间

问题描述

有什么方法可以在没有前向声明的情况下将朋友从模板导出到全局命名空间?

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)

标签: c++templates

解决方案


让我先说这是代码生成的一个不错且富有想象力的想法。但是没有办法公开友元函数以进行参数相关查找。

问题是 ADL 只考虑关联命名空间和类类型的朋友。对于要与类类型关联的枚举,它必须是类的成员,即flags专业化的成员。否则,无法将枚举与类类型(出于 ADL 目的)相关联。

在您的用例中,枚举显然不打算成为 of 的成员flags<MyEnum>,因此flags<MyEnum>在仅涉及MyEnum.


推荐阅读