我无法弄清楚为什么下面的代码(带有未定义的USE_TEMPLATE_SPECIALIZATION
)与Clang编译良好但使用Visual Studio 15.5.5失败:
#include <iostream>
#include <type_traits>
// Defining USE_TEMPLATE_SPECIALIZATION fixes MSVC but breaks CLang...
//#define USE_TEMPLATE_SPECIALIZATION
//-----------------------------------------------------
#ifdef USE_TEMPLATE_SPECIALIZATION
template<typename Enum>
struct EnableBitMaskOperators {
static const bool enable = false;
};
template<typename E>
constexpr typename std::enable_if<EnableBitMaskOperators<E>::enable, bool>::type
isSet(E e, E mask)
{
using underlying_t = typename std::underlying_type<E>::type;
return (static_cast<underlying_t>(e) & static_cast<underlying_t>(mask)) != 0;
}
#define ENABLE_BITMASK_OPERATORS(x) \
template<> \
struct EnableBitMaskOperators<x> { \
static const bool enable = true; \
};
#else //-------------------------------------------------
template<typename E>
constexpr bool enable_bitmask_operators(E) { return false; }
template<typename E>
constexpr typename std::enable_if<enable_bitmask_operators(E{}), bool>::type
isSet(E e, E mask)
{
using underlying_t = typename std::underlying_type<E>::type;
return (static_cast<underlying_t>(e) & static_cast<underlying_t>(mask)) != 0;
}
#define ENABLE_BITMASK_OPERATORS(x) constexpr bool enable_bitmask_operators(x){ return true; }
#endif
//-----------------------------------------------------
namespace NOne {
namespace NTwo {
enum class ENUM_FLAGS {
NONE = 0,
ONE = 1,
TWO = 2,
};
ENABLE_BITMASK_OPERATORS(ENUM_FLAGS);
}}
using namespace NOne::NTwo;
int main(int, char**)
{
auto a = ENUM_FLAGS::NONE;
std::cout << (isSet(a, ENUM_FLAGS::TWO)? "Should not happen" : "Bitwise flags work!") << std::endl;
return 0;
}
很清楚为什么在第5行中定义USE_TEMPLATE_SPECIALIZATION
会打破Clang,但令人惊讶的是,它修复了MSVC。
我真的想弄清楚为什么第二种方法,非模板函数重载,不适用于MSVC(我真的希望它不是MSVC错误,因为我相信它曾经工作过)并且会感激你的帮助!
谢谢你的期待!