【发布时间】:2021-02-11 02:19:13
【问题描述】:
我正在尝试这样做:
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 标准。
编辑:根据下面 Richard 的链接,我想出了这个似乎可以处理多次转换的情况,但不幸的是,每个运算符仍然需要 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";
}
【问题讨论】:
-
案例(2):非模板函数将尝试转换以匹配参数类型,
Number具有来自float的转换构造函数。情况 (1) 模板化函数不会尝试转换 - 在更复杂的情况下,当多个可能的转换可用时,参数应该是什么类型。另外对于情况(2)尝试制作构造函数explicit -
@RichardCritten 是的,我想这个标准通常是有意义的。但通常 c++ 的限制有解决方法,所以我希望有人能提供帮助。在这种特定情况下,正确的转换总是由其中一个 args 到二进制 op 恰好是 Number
. -
此处的示例(不需要 C++ 20 - 请参阅下面的答案 - 但您必须创建一些帮助模板)en.cppreference.com/w/cpp/language/… 具体定义
good(x, 1.2) -
这似乎会导致其他问题......我也在尝试添加一个向量,它通过 decltype(Vec1()[0] + Vec2( )[0]) 但 operator+ 不搜索转换重载并且替换失败。
标签: c++ type-conversion operator-overloading