繁体   English   中英

C++如何实现模板化转换二元运算符重载

[英]C++ how to implement templated converting binary operator overloads

我正在尝试这样做:

template<class Float>
struct Number {
  Float v;
  Number(Float iv = 0) : v(iv) {}
};

template<class F>
Number<F> operator+(Number<F> const& a, Number<F> const& b) {   
  return {a.v + b.v};
}

int main() {
  Number<float> y = Number<float>(1) + 2.0f;
  std::cout << y.v << "\n";
}

但它不起作用。

main.cpp:15:38: error: invalid operands to binary expression ('Number<float>' and
      'float')
  Number<float> y = Number<float>(1) + 2.0f;
                    ~~~~~~~~~~~~~~~~ ^ ~~~~
main.cpp:10:11: note: candidate template ignored: could not match
      'Number<type-parameter-0-0>' against 'float'
Number<F> operator+(Number<F> const& a, Number<F> const& b) {   
          ^

出于某种原因,这确实有效:

struct Number {
  float v;
  Number(float iv = 0) : v(iv) {}
};

Number operator+(Number const& a, Number const& b) { 
  return {a.v + b.v};
}

int main() {
  Number x = Number(1) + 2.0f;
  std::cout << x.v << "\n";
}

但我希望模板案例能够正常工作。 基本上,我正在寻找任何一种解决方法,以使我能够为 Number 实现二进制运算符,这将允许其中一个 args 可以转换为 Number。 最好符合 c++14。

编辑:基于下面理查德的链接,我想出了这个似乎可以处理多次转换的情况,但不幸的是仍然需要每个运算符的 3 个重载:

template<class T>
struct identity {
  using type = T;
};

template<class T>
using convertible = typename identity<T>::type;

template<class Float>
struct Param {
  Float v;
};

template<class Float>
struct Number {
  Float v;
  Number(Float iv = 0) : v(iv) {}
  Number(Param<Float> iv) : v(iv.v) {}
};

template<class F>
Number<F> operator+(Number<F> const& a, Number<F> const& b) {
  return {a.v + b.v};
}
template<class F>
Number<F> operator+(Number<F> const& a, convertible<Number<F>> const& b) {
  return {a.v + b.v};
}
template<class F>
Number<F> operator+(convertible<Number<F>> const& a, Number<F> const& b) {
  return {a.v + b.v};
}

int main() {
  std::cout << (Number<float>{1} + 2).v << "\n";
  std::cout << (Number<float>{1} + Param<float>{2}).v << "\n";
  std::cout << (Param<float>{1} + Number<float>{2}).v << "\n";
  std::cout << (Number<float>{1} + Number<float>{2}).v << "\n";
  std::cout << (1 + Number<float>{2}).v << "\n";
}

模板参数推导中不会考虑隐式转换。

类型推导不考虑隐式转换(除了上面列出的类型调整):这是 重载决议的工作,稍后会发生。

因此Number(1) + 2.0f中第二个 function 参数b对模板参数F的推导失败,不考虑从floatNumber<float>的隐式转换。

您可以添加另外两个重载为

template<class F, class V>
Number<F> operator+(Number<F> const& a, V const& b) {   
  return {a.v + Number{b}.v};
}

template<class F, class V>
Number<F> operator+(V const& a, Number<F> const& b) {   
  return {Number{a}.v + b.v};
}

居住

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM