Returning a struct from a class method

I have a header file that looks something like the following:

class Model {
 private:
  struct coord {
    int x;
    int y;
  } xy;
 public:
  ....
 coord get() const {
  return xy;
 }
};

And in yet another file (assume ModelObject exists):

struct c {
 int x;
 int y;
 void operator = (c &rhs) {
   x = rhs.x;
   y = rhs.y;
 };
} xy;

xy = ModelObject->get();

The compiler throws an error that says there is no known covnersion from coord to c. I believe it is because it doesn't know about coord type because it is declared inside of a class header. I can get around that by declaring the struct outside of the class, but I was wondering if it is possible to do the way I am, or is this generally considered bad practice

Answers


You would need an implicit conversion operator for Model::coord to c. For information on how to do this, I recommend taking a look at C++ Implicit Conversion Operators.

Also, when you mentioned "It does not know the type because it is in a class", you would use Model::coord as the struct type to the outside world (as long as coord is public, which in your current case it is not).


The code you have provided has two major problems: 1. You have not given a conversion from struct coord to struct c. 2. You can not use struct coord outside class Model because it is declared private.

  1. Even if struct coord and struct c are similar, the compiler has very limited psychic powers. For the compiler the two structs are different even if they do essentially the same. One way to solve this is to give struct c an adequate assignement operator which takes a type of struct coord:

    strutc c {  
        ...  
        void operator = (const coord& rhs) { ... }  
    };  
    
  2. You have to make struct coord more public to be used outside class Model. You can do this by: a) declaring struct coord outside the class Model or b) declaring it public inside class Model

    If you do the latter you have to use the qualified name Model::coord to access the struct.

Remarks: Consider changing the method

    coord Model::get() const;  

to

    const coord& Model::get() const;  

A subtle change that makes big difference. This saves an implicit construction of struct coord on the stack.

Consider changing the the operator

    void c::operator = (c &rhs);  

to

    void c::operator = (const c& rhs);  

because the assignment operator does not change the given argument struct c. Const correctness is not just syntactic sugar but mandatory and it improves readability.

So this is my suggestion:

class Model {
public:
    struct coord {
        int x; int y;
    };

private:
    coord xy;

public:
    const coord& get() const { return xy; }
};

struct c {
    int x; int y;

    void operator = (const c &rhs) { x = rhs.x; y = rhs.y; };
    void operator = (const Model::coord &rhs) { x = rhs.x; y = rhs.y; };
};  

Adding a constructor of c taking a coord is enough to make the compiler do the conversion. Now why do you have 2 different types for this ? Can't it be better to factorize this coord class out of Model and use them at both point ?


Need Your Help

Cancel new request instead of currently loading request when refreshing an image with Angular's $timeout

javascript angularjs

I'm using Angular's timeout to refresh the contents of an image at a user-specified interval. When that interval is too low for the image to load (e.g. 1 second), each subsequent request cancels the