boost::运算符的意外行为

Unintended behavior from boost::operators

本文关键字:意外 运算符 boost      更新时间:2023-10-16

我正在使用boost::operators(clang 2.1,boost 1.48.0)进行旋转,遇到了以下我无法解释的行为。当我将自己的operator double() const方法添加到我的类Ex中时(因为我希望允许我的用户在我的类的实例上习惯地使用static_cast<double>()),当我尝试在不同的类之间使用operator==时,似乎不再会出现编译器错误。实际上,似乎根本没有调用operator==

如果没有operator double() const,该类将完全按预期工作(除了它现在缺少转换运算符之外),并且在尝试f == h时,我收到了正确的编译器错误。

那么,添加这个转换运算符的正确方法是什么呢?下面的代码。

// clang++ -std=c++0x boost-operators-example.cpp -Wall -o ex  
#include <boost/operators.hpp>
#include <iostream>

template <typename T, int N>
class Ex : boost::operators<Ex<T,N>> {
 public:
  Ex(T data) : data_(data) {};
  Ex& operator=(const Ex& rhs) {
    data_ = rhs.data_;
    return *this;
  };
  T get() {
    return data_ * N;
  };
  // the troubling operator double()
  operator double() const {
    return double(data_) / N;
  };
  bool operator<(const Ex& rhs) const {
    return data_ < rhs.data_;
  };
  bool operator==(const Ex& rhs) const {
    return data_ == rhs.data_;
  };
 private:
  T data_;
};
int main(int argc, char **argv) {
  Ex<int,4> f(1);
  Ex<int,4> g(2);
  Ex<int,2> h(1);
  // this will fail for obvious reasons when operator double() is not defined
  //
  // error: cannot convert 'Ex<int, 4>' to 'double' without a conversion operator
  std::cout << static_cast<double>(f) << 'n';

  std::cout 
    // ok
    << (f == g) 
    // this is the error I'm supposed to get, but does not occur when I have
    // operator double() defined 
    //
    // error: invalid operands to binary expression 
    //  ('Ex<int, 4>' and 'Ex<int, 2>')
    // note: candidate function not viable: no known conversion from 
    //  'Ex<int, 2>' to 'const Ex<int, 4>' for 1st argument
    //   bool operator==(const Ex& rhs) const 
    << (f == h)  
    << 'n';
}

您应该将operator double()标记为显式。这允许静态强制转换,但防止在测试相等性时(以及在其他情况下)将其用作隐式转换。