2014-01-13 3 views
1

Я пишу коды C++ для платформы моделирования беспроводной связи. Мы используем арифметическую библиотеку с фиксированной точкой IT ++ (http://itpp.sourceforge.net/4.3.1/group__fixed.html). Наша цель - сделать арифметику с плавающей точкой и арифметикой с фиксированной точкой в ​​едином классе (с именем num_c), а алгоритмы могут быть записаны для класса num_c.Неоднозначный оператор при специализации std :: complex с пользовательским типом

Класс num_c - это шаблонный шаблон, полученный из num_base_c. Класс num_base_c инкапсулирует объект IT ++ Fix (http://itpp.sourceforge.net/4.3.1/classitpp_1_1Fix.html) и выглядит следующим образом (Простите, что я не могу напрямую скопировать вставку моих кодов, потому что они находятся в защищенной сети. Я постараюсь сделать список кодов максимально точным):

class num_base_c 
{ 
public: 
    // Default constructor 
    num_base_c(bool fix=false, double x=0.0, int w=itpp::MAX_WORDLEN, int s=0, itpp::emode e=itpp::TC, itpp::o_mode o=itpp::SAT, itpp::q_mode q=itpp::RND, itpp::Stat *ptr=0); 
    // Other constructors ... 

    // Conversion operator 
    operator double() const; 

    // Overloaded operators (including +=, -=, *=, -, +) 

protected: 
    bool m_flag_fixed; // true means fixed point number 
    double m_double; 
    itpp::Fix m_fix; 
}; 

класс num_c выглядит следующим образом:

// fix=true means fixed point value 
template <bool fix, int w=16, int s=0, itpp::e_mode e=itpp::TC, itpp::o_mode o=itpp::SAT, itpp::q_mode q=itpp::RND> 
class num_c : public num_base_c 
{ 
public: 
    // Default constructor 
    explicit num_c(double x=0.0, itpp::Stat *ptr=0) : num_base_c(fix, x, w, s, e, o, q, ptr) {} 
    // Other constructors ... 
    // Constructor from int 
    num_c(const int &x); 

    // Different versions of overloaded operator = (assignment from num_base_c, itpp::fixrep, or int) 
}; 

Я хочу, чтобы убедиться, является ли операция станда :: комплекс будет работать хорошо, когда специализирован с num_c, поэтому я проверил следующее:

using namespace std; 
using namespace itpp; 
complex< num_c<true, 16, 8, TC, SAT, RND> > c1(num_c<true, 16, 8, TC, SAT, RND>(1.3125, 0), num_c<true, 16, 8, TC, SAT, RND>(2.0625, 0)); 
num_c<true, 16, 8, TC, SAT, RND> n1(0, 0); 
n1 = abs(c1); 

В компиляции Visual Studio 2008 дает следующую ошибку (выдержка только одна из многих ошибок C2666): c: \ program files \ microsoft visual studio 9.0 \ vc \ include \ xcomplex (204): ошибка C2666: "operator < «: 2 перегруженные имеют аналогичные преобразования ... \ num_c_operators.h (16): может быть 'булев оператор < (Const num_base_c &, Const num_base_c &)' или 'родной C++ оператор < (двойной, Int)'

В моем номере num_c_operators.h, в строке 16, это объявлено:

extern bool operator<(const num_base_c& op1, const num_base_c& op2); 

Я думаю, что приведенный выше оператор <, а также «оператор double() const» и «num_c (const int & x)» являются причиной того, что компилятор попытался сопоставить оператор < (double, int). Однако мне нужен перегруженный оператор < для num_base_c. Мне также нужен оператор преобразования для double и constructor из int (иначе компилятор сообщит о других ошибках для std :: complex). Я не хочу писать совершенно другой сложный класс (на самом деле IT ++ предоставляет один), потому что существующие коды алгоритмов используют std :: complex. Итак, что я должен сделать, чтобы решить эту проблему?

Большое спасибо! Пэн

+0

Вы можете сделать конструктор и оператор явного преобразования? – jrok

+0

Спасибо за ответ. Боюсь, это непросто. Мы используем VS2008. Насколько я знаю, явный оператор преобразования - это функция C++ 11, поддерживаемая с Visual Studio 2013. Но если я ошибаюсь, пожалуйста, исправьте меня. – Peng

ответ

0

Есть варианты разрешения конфликта:

  • Отбросьте оператор преобразования
  • не имеет конструктора исполняющий неявное преобразование (делают конструктор явно)
  • или перегрузить все бинарные операторы.

Если перегрузка оператора вы можете сделать это следующим образом:

inline bool operator < (const num_base_c& a, const num_base_c& b) { 
    return ... 
} 

template <typename U> 
inline bool operator < (const num_base_c& a, const U& b) { 
    return ... 
} 

template <typename U> 
inline bool operator < (const U& a, const num_base_c& b) { 
    return ...; 
} 
+0

- Оператор преобразования не может быть отброшен, потому что некоторые сложные функции, такие как 'ldexp (_Ty _Left, int _Exponent) (в )', требуют преобразования в double. - Неявный конструктор преобразования требуется для 'complex (const _Ty & _Realval = 0, const _Ty & _Imageval = 0): Mybase (_Realval, _Imageval) {}'. - Я перегрузил двоичные операторы +, -, *, /,>, <, > =, <=, ==,! = Для num_base_c. По крайней мере, для <, компилятор не берет перегруженную версию и все еще запутан. – Peng

+0

Спасибо Дитер. Какова цель перегрузки бинарных операторов с использованием шаблона для одного из операндов? С шаблоном вызов оператора станет 'if (operator < (a1, a2)) {...}' вместо 'if (a1 , я боюсь, что лучше не изменять эти системные заголовки. – Peng

Смежные вопросы