Overloading operator= between objects of more than

2019-08-02 19:03发布

问题:

I'm defining three classes for my application: int2_ (couples of integers), float2_ (couples of floats) and double2_ (couples of doubles), essentially to perform complex arithmetics operations.

I want to overload the assignment = operator between objects of the above three classes. The motivation is that I'm writing a CUDA code, but it seems that there is no assignment operator already defined for the CUDA classes int2, float2 and double2.

My current implementation is the following:

class int2_ {

    public:
        int x;
        int y;

        int2_() : x(), y() {}

        // Stuff
        const int2_& operator=(const float2_ a)     { int2_ b;  b.x = (int)a.x;             b.y = (int)a.y;     return b; }
        const int2_& operator=(const double2_ a)    { int2_ b;  b.x = (int)a.x;             b.y = (int)a.y;     return b; }
};

class float2_ {

    public:
        float x;
        float y;

        float2_() : x(), y() {}

        // Stuff
        const float2_& operator=(const double2_ a)  { float2_ b;    b.x = (float)a.x;       b.y = (float)a.y;   return b; }
};

class double2_ {

    public:
        double x;
        double y;

        double2_() : x(), y() {}

        // Stuff
};

Everything is summarized as stuff does not provide compilation errors. The remaining operator overloads return the following errors

error : identifier "float2_" is undefined
error : identifier "double2_" is undefined  
error : identifier "double2_" is undefined  

respectively for the three different overloads.

It seems that there is a "visibility" problem due to the fact that, for example, float2_ and double2_ are not yet defined before the int2_ class definition. Any suggestion on how solving the problem? Thank you very much in advance.

SOLUTION FOLLOWING THE ANSWERS OF JAMES KANZE AND ALEXRIDER

Here is the solution:

class int2_;
class float2_;
class double2_;

class int2_ {

    public:
        int x;
        int y;

        int2_() : x(), y() {}

        inline const int2_& operator=(const int a)          { x = a;            y = 0.;         return *this; }
        inline const int2_& operator=(const float a)        { x = (int)a;       y = 0.;         return *this; }
        inline const int2_& operator=(const double a)       { x = (int)a;       y = 0.;         return *this; }
        inline const int2_& operator=(const int2_ a)        { x = a.x;          y = a.y;        return *this; }
        inline const int2_& operator=(const float2_ a);
        inline const int2_& operator=(const double2_ a);
};

class float2_ {

    public:
        float x;
        float y;

        float2_() : x(), y() {}

        inline const float2_& operator=(const int a)        { x = (float)a;     y = 0.;         return *this; }
        inline const float2_& operator=(const float a)      { x = a;            y = 0.;         return *this; }
        inline const float2_& operator=(const double a) { x = (float)a;     y = 0.;         return *this; }
        inline const float2_& operator=(const int2_ a)      { x = (float)a.x;   y = (float)a.y; return *this; }
        inline const float2_& operator=(const float2_ a)    { x = a.x;          y = a.y;        return *this; }
        inline const float2_& operator=(const double2_ a);
};

class double2_ {

    public:
        double x;
        double y;

        double2_() : x(), y() {}

        inline const double2_& operator=(const int a)       { x = (double)a;    y = 0.;         return *this; }
        inline const double2_& operator=(const float a) { x = (double)a;    y = 0.;         return *this; }
        inline const double2_& operator=(const double a)    { x = a;            y = 0.;         return *this; }
        inline const double2_& operator=(const int2_ a) { x = (double)a.x;  y = (double)a.y;return *this; }
        inline const double2_& operator=(const float2_ a)   { x = (double)a.x;  y = (double)a.y;return *this; }
        inline const double2_& operator=(const double2_ a)  { x = a.x;          y = a.y;        return *this; }

};

        inline const int2_& int2_::operator=(const float2_ a)       { x = (int)a.x;             y = (int)a.y;       return *this; }
        inline const int2_& int2_::operator=(const double2_ a)      { x = (int)a.x;             y = (int)a.y;       return *this; }
        inline const float2_& float2_::operator=(const double2_ a)  { x = (float)a.x;           y = (float)a.y;     return *this; }

回答1:

First, you need to use forward declarations of the classes:

class Int2;
class Float2;
class Double2;

Then, in the classes, you should only declare the functions, not implement them. The implementations should come after all of the class definitions, either in a separate source file, or explicitly declared inline.



回答2:

You need to change order of your classes declaration as following.
Forward declaration won't help in this case, since you need type to be declared to be used in operator=

class double2_ {

    public:
        double x;
        double y;

        double2_() : x(), y() {}

        // Stuff
};

class float2_ {

    public:
        float x;
        float y;

        float2_() : x(), y() {}

        // Stuff
        const float2_& operator=(const double2_ a)  { float2_ b;    b.x = (float)a.x;       b.y = (float)a.y;   return b; }
};


class int2_ {

    public:
        int x;
        int y;

        int2_() : x(), y() {}

        // Stuff
        const int2_& operator=(const float2_ a)     { int2_ b;  b.x = (int)a.x;             b.y = (int)a.y;     return b; }
        const int2_& operator=(const double2_ a)    { int2_ b;  b.x = (int)a.x;             b.y = (int)a.y;     return b; }
};

Also there is a problem with operator= itself, it should return *this; instead of b that will go out of scope right after operator= does it's job.



回答3:

The problem is that float2_ is defined only after int2_, where it is already used. Add a forward declaration of these two classes and you should be fine:

class int2_;
class double2_;