我遗漏了std::complex
的一些重要功能,例如添加std::complex<float>
和std::complex<double>
或1+c
之类的操作,即int
之间的操作和std::complex
。我的想法是从my::complex
派生一个新类std::complex
,它只是继承已经实现的所有内容并添加其他内容。
为了使代码与使用std::complex
的函数兼容,我添加了std::complex
的自动转换(以及my::complex<float>
和my::complex<double>
之间的自动转换)。
现在像
my::complex<float> c1,c2,c3;
c1 = c2 + c3;
虽然我自己没有实现operator+
,但是c2
和c3
被强制转换为std::complex
,然后添加并将结果转换回my::complex
}。我假设编译器可以优化任何实际的复制。
但是,以下情况不起作用:
c1 = 2*(c2+c3)
因为std::complex
不能乘以一个整数(如果我乘以一个double并且有complex<float>
s则会出现同样的问题。)
我想&#34;好吧,似乎我必须在{#1}之后添加operator+
,但如果我这样做,我得到use of overloaded operator '+' is ambiguous
,因为编译器可以在{{1}之间}}和std::complex
含蓄地。
有没有更好的方法来实现我想要或做的事情我需要完全重新实现my::complex
中的所有内容并抛弃继承?
答案 0 :(得分:7)
将这些重载添加为自由函数可能与完成任何工作一样好。但是,我不会为每对可能的操作数类型编写一个单独的硬编码 - 这会很快变得乏味。
相反,你无疑想要编写一个模板函数来处理任何一对操作数类型。关于这个一般顺序的东西:
template <class T, class U>
auto operator*(T const &a, U const &b) -> typename std::common_type<T, U>::type
{
// code to produce the equivalent of: return a * b;
}
这样,如果您将complex<double>
乘以int
而将complex<float>
乘以double
(等),则不必复制该函数对于每种可能的组合(如果您尝试组合两种不具有共同类型的类型,例如complex<double>
和std::string
,则它只是不会编译)。
在这种情况下,填充正文非常简单:我们有两种不同类型的输入,但我们知道(或可以推断)与两者兼容的常见类型。我们希望将每个输入转换为该公共类型,并对转换结果执行操作:
template <class T, class U>
auto operator*(T const &a, U const &b) -> typename std::common_type<T, U>::type
{
using ret_type = typename std::common_type<T, U>::type;
return ret_type(a) * ret_type(b);
}
答案 1 :(得分:6)
为了添加复杂数量的不同类型和其他运算符,我将使用自由函数
std::complex<double> operator? (std::complex<double> a,std::complex<float> b){
std::complex<double> result;
// implement ?
return result;
}
std::complex<double> operator? (std::complex<float> a,std::complex<double> b){
return b ? a;
}
其中?
是您想要的运营商的地方。请注意,这是一个pre-C ++ 11解决方案,更好的方式请参阅Jerry Coffins answer。
为了向复合体添加数字,例如在1+c
中,我不会努力编写运算符,而只需使用c+1
代替(实际上我不确定这是否适用于{ {1}}但如果不是,我会感到惊讶)。