二进制表达式的C++操作数无效

C++ invalid operands to binary expression

本文关键字:操作数 无效 C++ 表达式 二进制      更新时间:2023-10-16

我在C++11中遇到了一个奇怪的编译错误。

我有一个模板化的类,它定义了一个枚举类:

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();
 }

在这里我们可以像这个CCD_ 1一样调用这个函数。

为了在该枚举上使用&|运算符,而不必每次手动转换为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);
  • 我认为问题来自返回类型,但调用stat a = stats & stat::AVERAGE;不起作用(与前面的错误相同)

知道吗?

您的代码有两个错误。

  1. 这是一个不可推导的上下文:

    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&:使其成为类本身的友元运算符:

    friend stat operator&(const stat& lhs, const stat& rhs) { ... }
    
  2. 一旦我们解决了这个问题,我们就会遇到另一个问题,那就是stat不能在上下文中转换为stats.build(stat::AVERAGE | stat::LIMITS)0,所以这个表达式:

    if (stats & stat::AVERAGE)
    

    不会编译。为此,您可能希望operator&返回intbool,或者使用此答案的想法,添加operator!并使用两次。