문제

실제 및 복잡한 데이터 유형을 정의하는 두 개의 래퍼 클래스를 작업 중입니다. 각 클래스는 과부하 된 생성자와 4 개의 산술 연산자 +,-,*,/ 및 5 개의 할당 연산자 =, += 등을 정의합니다. -연산자의 핸드 사이드 인수는 다른 데이터 유형입니다.

// 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'에서 '연산자 *'에 대한 모호한 과부하, 컴파일러가 다음의 차이를 알 수 없으므로 다음과 같습니다.

  • template <class T> friend const Complex operator*(const Complex&, const T&) t = real 포함
  • template <class T> friend const Real operator*(const T&, cont Real&) t = complex)

클래스 real의 템플릿 연산자* 정의에서 t가 복잡 할 수 없음을 지정하는 방법이 있습니까? 아니면 템플릿없이 수행해야하고 인수 데이터 유형의 가능한 모든 조합에 대해 각 연산자를 정의해야합니까? 아니면 코드를 재 설계하는 방법이 있습니까?

도움이 되었습니까?

해결책

아, 운영자의 문제 ...

부스트는 멋진 라이브러리를 만들어 최소의 논리를 제공함으로써 다른 모든 변형을 자동으로 추가 할 수 있도록했습니다!

보세요 부스트. 오퍼레이터 !

이제 당신의 문제에 대해, 실제로 당신이 알았 듯이, 당신은 일반 템플릿을 사용하지 않고 연산자의 두 맛 (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 :: 연산자 만 제공하며 독립형 버전은 자동으로 추론됩니다 :)

(1) 모든 인수가 내장되어 있다면 여기에서 Pass By-Value를 사용할 수 있습니다. 당신은 또한 고려하고 싶을 수도 있습니다 Boost.calltraits, 인수가 내장되어 있는지 여부에 따라 자동으로 부가가치와 REF를 자동으로 선택합니다. 템플릿에 편리합니다.

(2) 가치로 인수를 반환 할 때, 그들을 const. 그만큼 const 키워드는 참조와 포인터에 대한 것을 의미합니다. 여기서 사용자가 '단순'을 인스턴스화하는 것은 아무것도 없습니다. Complex... 그리고 당신은 운이 좋지 않습니다!

다른 팁

실제 또는 복잡한 클래스에 비 글로벌 곱셈 연산자가있게 만들 수 있습니다.

class Real 
{
  ........

  template <class T> const Real operator*(const T&);
  const Real operator*(const Real&);

};

복잡한 생성자를 명시 적으로 만들 수 있습니까? 이는 실제에서 복잡한 것으로 암시 적 변환이 허용되지 않으며 운영자를 명확하게해야한다는 것을 의미합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top