gpt4 book ai didi

c++ - 模板运算符的不明确重载

转载 作者:搜寻专家 更新时间:2023-10-31 02:00:44 24 4
gpt4 key购买 nike

我正在研究两个定​​义真实和复杂数据类型的包装器类。每个类都定义了重载的构造函数,还有四个算术运算符+、-、*、/和五个赋值运算符=、+=等。为了避免重复代码,我想在左右时使用模板函数- 运算符的手边参数是不同的数据类型:

// real.h
class Real {
public:
explicit Real(const double& argument) {...}
explicit Real(int argument) {...}
...

friend const operator*(const Real&; const Real&);
template <class T> friend const Real operator*(const Real&, const T&);
template <class T> friend const Real operator*(const T&, cont Real&);
// Here, T is meant to be a template parameter for double and int

// Repeat for all other arithmetic and assignment operators
};

// complex.h
class Complex {
public:
explicit Complex(const Real& realPart) {...}
explicit Complex(const Real& realPart, const Real& imaginaryPart) {...}
// Overload for double and int data types
...

friend const operator*(const Complex&, const Complex&);
template <class T> friend const Complex operator*(const Complex&, const T&);
template <class T> friend const Complex operator*(const T&, cont Complex&);
// Here, T is is a template parameter for Real, double and int

...
};

这里的问题是这样的代码:

//main.cpp
void main() {
Complex ac(2.0, 3.0);
Real br(2.0);
Complex cc = ac * br;
}

返回编译器 (gcc) 错误'ac * br' 中'operator*' 的不明确重载,因为编译器无法分辨以下两者之间的区别:

  • template <class T> friend const Complex operator*(const Complex&, const T&) [with T = Real]
  • template <class T> friend const Real operator*(const T&, cont Real&) [with T = Complex]

有没有办法在 Real 类的模板 operator* 定义中指定 T 不能是 Complex?或者我是否必须在没有模板的情况下为每个可能的参数数据类型组合定义每个运算符?或者有没有办法重新设计代码?

最佳答案

啊,运算符的问题...

Boost 创建了一个不错的库,因此通过提供最少的逻辑,所有其他变体都会自动为您添加!

看看Boost.Operators !

现在针对您的问题,实际上正如您注意到的那样,您将必须定义两种类型的运算符(int 和 double),而不是使用通用模板。如果这些运算符中有很多逻辑(我对此表示怀疑),您始终可以让它们调用通用(模板化)方法。

template <typename T>
Complex complex_mult_impl(T const& lhs, Complex const& rhs) { ... } // Note (1)

// return type is not 'Complex const', see (2)
Complex operator*(int lhs, Complex const& rhs)
{
return complex_mult_impl(lhs,rhs);
}

但是如果你使用 Boost.operators 你只需要提供 Complex::operator*=(int) 和 Complex::operator*=(double) 并且独立版本会被自动推导:)

(1) 如果所有参数都是内置参数,您可以在此处使用按值传递。您可能还想考虑 Boost.CallTraits ,它根据参数是否内置,自动在 by-value 和 by-ref 之间进行选择。这对于模板很方便。

(2) 按值返回参数时,将它们限定为const 是没有意义的。 const 关键字仅表示引用和指针,这里没有什么可以阻止用户实例化“简单”Complex...您很幸运,它没有!

关于c++ - 模板运算符的不明确重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1629829/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com