有没有一种方法可以使用其他运算符扩展类?

Vik*_*ick 9 c++ inheritance operator-overloading

我一直缺少一些重要的功能,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;
Run Code Online (Sandbox Code Playgroud)

即使我没有实现operator+自己,因为c2并且c3被强制转换std::complex,添加并且结果被转换为my::complex.我假设编译器可以优化任何实际的复制.

但是,以下不起作用:

c1 = 2*(c2+c3)
Run Code Online (Sandbox Code Playgroud)

因为std::complex不能乘以一个整数(相同的问题,如果我乘以一个double并有complex<float>s).

我想:"好吧,看来我必须添加operator+的所有后",但如果我这样做,我得到的use of overloaded operator '+' is ambiguous,因为编译器之间std::complexmy::complex含蓄.

有没有更好的方法来实现我想要或做的事情我需要完全重新实现所有内容std::complex并抛弃继承?

Jer*_*fin 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;
}
Run Code Online (Sandbox Code Playgroud)

这样,如果你乘一个complex<double>intcomplex<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);
}
Run Code Online (Sandbox Code Playgroud)


for*_*818 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;
}
Run Code Online (Sandbox Code Playgroud)

在哪里?是您想要的运营商的地方.请注意,这是一个pre-C++ 11解决方案,对于一个更好的方式,请参阅Jerry Coffins的回答.

为了向复合体添加一个数字,比如在中1+c,我不会努力编写一个操作符,而只是简单地使用c+1(实际上我不确定这是否适用std::complex但如果没有我会感到惊讶).