簡體   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