[英]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.