Sim*_*non 0 c++ enums compilation bitwise-operators c++11
我在C++ 11中遇到了一个奇怪的编译错误.
我有一个模板化的类来定义一个枚举类:
template <typename Type>
class stats {
public:
// ...
enum class stat {
AVERAGE = (1 << 0),
STANDARD_DERIVATION = (1 << 1),
// ...
};
// ...
};
Run Code Online (Sandbox Code Playgroud)
我目前想在按位运算中使用这个枚举.
例如,以下是该枚举的用法示例:
template <typename Type>
void
stats<Type>::build(stat stats) {
if (stats & stat::AVERAGE)
this->build_average();
if (stats & stat::STANDARD_DEVIATION)
this->build_standard_deviation();
if (stats & stat::PERCENTILES)
this->build_percentiles();
if (stats & stat::LIMITS)
this->build_limits();
}
Run Code Online (Sandbox Code Playgroud)
我们可以在这里调用这个函数stats.build(stat::AVERAGE | stat::LIMITS).
为了在枚举上使用&或|运算符而不必每次都手动转换为int,我已经定义了运算符:
template<typename T>
using stat_t = typename eip::stats<T>::stat;
template <typename Type>
stat_t<Type>
operator|(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
return static_cast<stat_t<Type>>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
template <typename Type>
stat_t<Type>
operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
return static_cast<stat_t<Type>>(static_cast<int>(lhs) & static_cast<int>(rhs));
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试编译,我会收到以下错误:
error: invalid operands to binary expression ('eip::stats<double>::stat' and 'eip::stats<double>::stat')
if (stats & stat::PERCENTILES)
~~~~~ ^ ~~~~~~~~~~~~~~~~~
candidate template ignored: couldn't infer template argument 'Type'
operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
^
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我的重载被忽略了.似乎编译器为lhs和rhs(eip::stats<double>::stat)获取了正确的类型,但它无法推断模板......
此外:
operator&<Type>(stats, stat::AVERAGE);)stat a = stats & stat::AVERAGE;不起作用(与之前相同的错误).任何的想法?
您的代码有两个问题.
这是一个不可导出的背景:
template <typename Type>
stat_t<Type>
operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) { ... }
Run Code Online (Sandbox Code Playgroud)
这个想法和你写的一样:
template <typename T>
void foo(typename cls<T>::type ) { ... }
Run Code Online (Sandbox Code Playgroud)
T除非你告诉它,否则编译器无法弄清楚可能存在的东西.因此,您必须operator&在我们实际上不需要进行演绎的地方定义您:在类本身中将其设置为友元运算符:
friend stat operator&(const stat& lhs, const stat& rhs) { ... }
Run Code Online (Sandbox Code Playgroud)一旦我们解决了这个问题,我们就会遇到另一个问题,即a stat不能在上下文中转换成bool这样的表达式:
if (stats & stat::AVERAGE)
Run Code Online (Sandbox Code Playgroud)
不会编译.为此,你可能希望让你的operator&回报int或bool,或者使用这个答案的想法,添加operator!并使用它两次.