[英]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
的推導失敗,不考慮從float
到Number<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.