I'm attempting to use an approach which allows for automatic enabling of bitmask operators for strongly typed enum classes. See below header and cpp of an example.
https://www.justsoftwaresolutions.co.uk/files/bitmask_operators.hpp https://www.justsoftwaresolutions.co.uk/files/testbitmask.cpp
The approach in testbitmask.cpp works when everything is in the same namespace, however I would like to separate the SFINAE code in a different namespace from the usage by other classes (see below or 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;
}
This has the effect of not being able to find the overloaded operator in main. Explicitly calling the function works (TWO::A a1 = ONE::operator|(TWO::A::x , TWO::A::y);
), but of course is not the desired functionality.
If we move the specialization into namespace ONE
, the compiler throws an error: declaration of 'struct ONE::enable_bitmask_operators<TWO::A>' in namespace 'TWO' which does not enclose 'ONE'
. I'm wondering if the desired approach is possible in C++?
Your function cannot be found by ADL, you might add some using
to allow to use it:
using ONE::operator|;
TWO::A a1 = TWO::A::x | TWO::A::y;
using namespace ONE;
might be an alternative too.