【问题标题】:SFINAE-based Operator Overloading across Namespaces跨命名空间的基于 SFINAE 的运算符重载
【发布时间】:2019-06-18 11:13:40
【问题描述】:

我正在尝试使用一种方法,该方法允许为强类型枚举类自动启用位掩码运算符。请参阅下面的示例标题和 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&lt;TWO::A&gt;' in namespace 'TWO' which does not enclose 'ONE'。我想知道在 C++ 中是否可以使用所需的方法?

【问题讨论】:

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


    【解决方案1】:

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

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

    Demo

    using namespace ONE; 也可能是另一种选择。

    【讨论】:

    • 我认为这是可以接受的 - 不希望在使用枚举的每个 cpp 中都需要 using,并且理想情况下不希望在标题中包含 using ONE::operator|,因为它非常通用。我可以忍受将枚举类包装在另一个命名空间中并在其中使用它。会再等一天,以防有其他方法,但我相信没有。
    • 类似于operator ""s'对std的用法。
    猜你喜欢
    • 2011-12-03
    • 1970-01-01
    • 2019-02-05
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多