1
votes

I'm writing C++ codes for a wireless communication simulation platform. We use the fixed point arithmetic library of IT++ (http://itpp.sourceforge.net/4.3.1/group__fixed.html). Our objective is to make floating point and fixed point arithmetic be wrapped in a unified class (named num_c), and algorithms can be written for the num_c class.

The num_c class is a templated class derived from num_base_c. The num_base_c class encapsulates an IT++ Fix (http://itpp.sourceforge.net/4.3.1/classitpp_1_1Fix.html) object and looks like this (Forgive me I cannot directly copy paste my codes because they are in a secured network. I'll try to make the code list as accurate as possible):

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;
};

The num_c class looks like this:

// 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)
};

I want to make sure whether the operations of std::complex will work fine when specialized with num_c, so I tested the following:

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);

In compilation, Visual Studio 2008 gives the following error (excerpt only one among many C2666 errors): c:\program files\microsoft visual studio 9.0\vc\include\xcomplex (204): error C2666: "operator <": 2 overloads have similar conversions ...\num_c_operators.h(16): could be 'bool operator <(const num_base_c &, const num_base_c &)' or 'native C++ operator<(double, int)'

In my num_c_operators.h, at line 16, I have this declared:

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

I think the above operator<, plus the "operator double() const" and "num_c(const int &x)" are the reason that compiler tried to match operator<(double, int). However I do need the overloaded operator< for num_base_c. I also need the conversion operator to double and constructor from int (otherwise compiler will report other errors for std::complex). I don't want to write a completely different complex class (actually IT++ provides one), because existing algorithm codes are using std::complex. So what should I do to resolve this?

Many many thanks! Peng

1
Can you make the constructor and the conversion operator explicit? - jrok
Thanks for the answer. I'm afraid it's not easy. We are using VS2008. As far as I know explicit conversion operator is a C++11 feature supported since Visual Studio 2013. But if I'm wrong, please correct me. - Peng

1 Answers

0
votes

There are options to resolve the conflict:

  • Drop the conversion operator
  • have no constructor performing an implicit conversion (make constructors explicit)
  • or overload all binary operators.

If you overload operator you might do it this way:

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 ...;
}