C++ 二进制表达式的无效操作数
C++ invalid operands to binary expression
我在 C++11 中遇到奇怪的编译错误。
我有一个模板化的 class 定义了一个枚举 class:
template <typename Type>
class stats {
public:
// ...
enum class stat {
AVERAGE = (1 << 0),
STANDARD_DERIVATION = (1 << 1),
// ...
};
// ...
};
我目前想在按位运算中使用这个枚举。
例如,这是该枚举的用法示例:
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();
}
在哪里我们可以像这样调用这个函数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));
}
但是,如果我尝试编译,我会收到以下错误:
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) {
^
我不明白为什么我的过载被忽略了。编译器似乎为 lhs 和 rhs (eip::stats<double>::stat
) 获得了正确的类型,但它无法推断模板...
此外:
- 显式调用运算符有效 (
operator&<Type>(stats, stat::AVERAGE);
)
- 我认为问题出在 return 类型,但调用
stat a = stats & stat::AVERAGE;
不起作用(与之前的错误相同)。
有什么想法吗?
您的代码有两处错误。
这是一个不可推导的上下文:
template <typename Type>
stat_t<Type>
operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) { ... }
思路和你写的一样:
template <typename T>
void foo(typename cls<T>::type ) { ... }
编译器无法弄清楚 T
可能在那里,除非你也告诉它。所以你必须在我们实际上不需要进行推导的地方定义你的 operator&
:让它成为 class 本身的友元运算符:
friend stat operator&(const stat& lhs, const stat& rhs) { ... }
一旦我们解决了这个问题,我们就会遇到另一个问题,即 stat
不能根据上下文转换为 bool
所以这个表达式:
if (stats & stat::AVERAGE)
无法编译。为此,您可能希望让您的 operator&
return 成为 int
或 bool
,或者使用 this answer 的想法,添加一个 operator!
并使用它两次。
我在 C++11 中遇到奇怪的编译错误。
我有一个模板化的 class 定义了一个枚举 class:
template <typename Type>
class stats {
public:
// ...
enum class stat {
AVERAGE = (1 << 0),
STANDARD_DERIVATION = (1 << 1),
// ...
};
// ...
};
我目前想在按位运算中使用这个枚举。
例如,这是该枚举的用法示例:
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();
}
在哪里我们可以像这样调用这个函数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));
}
但是,如果我尝试编译,我会收到以下错误:
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) {
^
我不明白为什么我的过载被忽略了。编译器似乎为 lhs 和 rhs (eip::stats<double>::stat
) 获得了正确的类型,但它无法推断模板...
此外:
- 显式调用运算符有效 (
operator&<Type>(stats, stat::AVERAGE);
) - 我认为问题出在 return 类型,但调用
stat a = stats & stat::AVERAGE;
不起作用(与之前的错误相同)。
有什么想法吗?
您的代码有两处错误。
这是一个不可推导的上下文:
template <typename Type> stat_t<Type> operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) { ... }
思路和你写的一样:
template <typename T> void foo(typename cls<T>::type ) { ... }
编译器无法弄清楚
T
可能在那里,除非你也告诉它。所以你必须在我们实际上不需要进行推导的地方定义你的operator&
:让它成为 class 本身的友元运算符:friend stat operator&(const stat& lhs, const stat& rhs) { ... }
一旦我们解决了这个问题,我们就会遇到另一个问题,即
stat
不能根据上下文转换为bool
所以这个表达式:if (stats & stat::AVERAGE)
无法编译。为此,您可能希望让您的
operator&
return 成为int
或bool
,或者使用 this answer 的想法,添加一个operator!
并使用它两次。