我正在尝试为按位<<操作符编写通用模板重载,但是我很难指定操作符的左侧是枚举,并且编译器给我一个“模棱两可的重载”错误。
我希望static_assert告诉编译器“文件<< x”中的<<操作符不是我定义的模板,然后它将选择iostream中定义的<<操作符。但是,我收到一条编译器消息,指出两者是不明确的。
“ cout << x”没有此问题。
#include <fstream>
#include <iostream>
using namespace std;
enum DAY{MON=1,TUES=2,WED=4,THUR=8,FRI=16};
template<typename Enum>
constexpr Enum operator <<(Enum e,int n)
{
static_assert(std::is_enum<Enum>::value,
"template parameter is not an enum type");
using underlying = typename std::underlying_type<Enum>::type;
return static_cast<Enum> ( static_cast<underlying>(e) << n );
}
int main()
{
// this does as I'd like
DAY day = MON;
day = static_cast<DAY>(day << 2); // this is the behavior I need
cout << day << endl;
// but this is ambiguous
ofstream file("test.dat");
float x;
file << x; // this line is ambigous
return 0;
}
答案 0 :(得分:3)
static_assert
适用于从过载解析中删除operator<<
的时间太晚。您需要改用SFINAE。这样的事情会做你想要的:
template <typename Enum>
constexpr std::enable_if_t<std::is_enum_v<Enum>, Enum>
operator<<(Enum e, int n)
{
using underlying = typename std::underlying_type_t<Enum>;
return static_cast<Enum> ( static_cast<underlying>(e) << n );
}