c++ - 基于 SFINAE 的运算符跨命名空间重载

标签 c++ templates namespaces operator-overloading argument-dependent-lookup

我正在尝试使用一种允许为强类型枚举类自动启用位掩码运算符的方法。请参阅下面的示例标题和 cpp。

https://www.justsoftwaresolutions.co.uk/files/bitmask_operators.hpp https://www.justsoftwaresolutions.co.uk/files/testbitmask.cpp

testbitmask.cpp 中的方法在所有内容都在同一个命名空间中时有效,但是我想将不同命名空间中的 SFINAE 代码与其他类的使用分开(见下文或 https://wandbox.org/permlink/05xXaViZT3MVyiBl)。

#include <type_traits>

namespace ONE {
    template<typename E>
    struct enable_bitmask_operators{
        static const bool enable=false;
    };

    template<typename E>
    inline typename std::enable_if<enable_bitmask_operators<E>::enable,E>::type
    operator|(E lhs,E rhs){
        typedef typename std::underlying_type<E>::type underlying;
        return static_cast<E>(
            static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
    }
}

namespace TWO {
    enum class A{ x=1, y=2};
}

namespace ONE {
    template<>
    struct enable_bitmask_operators<TWO::A>{
        static const bool enable=true;
    };
}

int main(){
    TWO::A a1 = TWO::A::x | TWO::A::y;
}

这具有无法在 main 中找到重载运算符的效果。显式调用该函数有效 ( TWO::A a1 = ONE::operator|(TWO::A::x , TWO::A::y); ),但当然不是所需的功能。

如果我们将特化移动到 namespace ONE , 编译器抛出 error: declaration of 'struct ONE::enable_bitmask_operators<TWO::A>' in namespace 'TWO' which does not enclose 'ONE' .我想知道在 C++ 中是否可以实现所需的方法?

最佳答案

ADL 无法找到您的函数,您可以添加一些using 以允许使用它:

using ONE::operator|;
TWO::A a1 = TWO::A::x | TWO::A::y;

Demo

using namespace ONE; 也可能是一种替代方法。

关于c++ - 基于 SFINAE 的运算符跨命名空间重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54351375/

相关文章:

C++ dynamic_cast 异常

声明模板类成员和构造函数时的 C++ 习语

c++ - 返回不同类型的模板函数

namespaces - 按模式查找 hiera 配置

c++ - 为什么这不能在我的学校 unix 系统上编译?

c++ - sizeof(enum) 与 sizeof(std::underlying_type<Enum>::type) 可以不同吗?

C++创建导致段错误的新数组

javascript - 无法返回 meteor 中的默认模板

c++ - 如何转发声明在命名空间中的类

c# - 移动/更新命名空间声明时如何阻止 ReSharper 删除未使用的 Using 语句?