用户定义的转换运算符不适用于引用

时间:2017-03-15 20:08:29

标签: c++ templates casting reference user-defined

我有一个简单的原始类型包装器:

template <typename T>
class Scalar {
 public:
  explicit Scalar(T value) : value{value} {}

  Scalar(Scalar&& other) = default;
  Scalar& operator=(Scalar&& other) = default;
  Scalar(const Scalar& other) = default;
  Scalar& operator=(const Scalar& other) = default;

  template <typename U>
  explicit operator Scalar<U>() {
    return Scalar<U>{static_cast<U>(this->value)};
  }

  inline T getValue() const noexcept { return this->value; }
 private:
  T value;
};

Casting Scalar值运行良好,但不知何故它无法用于引用,例如

auto a = Scalar<double>{2.54};
Scalar<int> b = static_cast<Scalar<int>>(a); // works

const auto& c = a;
Scalar<int> d = static_cast<Scalar<int>>(c); // fails

这是编译错误(可以在这里查看http://rextester.com/GOPYU13091),任何想法可能会出现在这里?

source_file.cpp: In function ‘int main()’:
source_file.cpp:31:47: error: no matching function for call to ‘Scalar(const Scalar<double>&)’
     Scalar<int> d = static_cast<Scalar<int>>(c);
                                               ^
source_file.cpp:12:3: note: candidate: Scalar<T>::Scalar(const Scalar<T>&) [with T = int] <near match>
   Scalar(const Scalar& other) = default;
   ^
source_file.cpp:12:3: note:   conversion of argument 1 would be ill-formed:
source_file.cpp:31:47: error: could not convert ‘c’ from ‘const Scalar<double>’ to ‘const Scalar<int>&’
     Scalar<int> d = static_cast<Scalar<int>>(c);
                                               ^
source_file.cpp:10:3: note: candidate: Scalar<T>::Scalar(Scalar<T>&&) [with T = int] <near match>
   Scalar(Scalar&& other) = default;
   ^
source_file.cpp:10:3: note:   conversion of argument 1 would be ill-formed:
source_file.cpp:31:47: error: could not convert ‘c’ from ‘const Scalar<double>’ to ‘Scalar<int>&&’
     Scalar<int> d = static_cast<Scalar<int>>(c);
                                               ^

1 个答案:

答案 0 :(得分:5)

这是const与非const问题,而非参考与对象问题。

使用

auto& c = a;
Scalar<int> d = static_cast<Scalar<int>>(c);

适合我。

将用户定义的转换运算符更改为const成员函数

template <typename U>
explicit operator Scalar<U>() const {
  return Scalar<U>{static_cast<U>(this->value)};
}

还确保以下工作。

const auto& c = a;
Scalar<int> d = static_cast<Scalar<int>>(c);