Maik Klein
Maik Klein

Reputation: 16148

How do I create an object variable from a function call?

We are using an custom image class written by our professor. I can load images like this

SimpleGrayImage in("images/uni01.pgm");

Now I have a function that looks like this

SimpleGrayImage apply_mask(SimpleGrayImage &img,SimpleFloatImage &mask){

and I can also uses methods on it like this apply_mask(...).show();

But I am not allowed to do this SimpleGrayImage img = apply_mask(...);

Did I miss something or could it be that our professor forgot to add another constructor?

test.cpp:133:43: error: no matching function for call to ‘SimpleGrayImage::SimpleGrayImage(SimpleGrayImage)’
   SimpleGrayImage img = apply_mask(in,mask);
                                           ^
test:133:43: note: candidates are:
In file included from SimpleFloatImage.h:13:0,
                 from aufgabe11_12_13.cpp:13:
SimpleGrayImage.h:110:2: note: SimpleGrayImage::SimpleGrayImage(const string&)
  SimpleGrayImage(const std::string& filename);
  ^
SimpleGrayImage.h:110:2: note:   no known conversion for argument 1 from ‘SimpleGrayImage’ to ‘const string& {aka const std::basic_string<char>&}’
SimpleGrayImage.h:91:2: note: SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)
  SimpleGrayImage(SimpleGrayImage &img);
  ^
SimpleGrayImage.h:91:2: note:   no known conversion for argument 1 from ‘SimpleGrayImage’ to ‘SimpleGrayImage&’
SimpleGrayImage.h:86:2: note: SimpleGrayImage::SimpleGrayImage(int, int)
  SimpleGrayImage(int wid, int hig);
  ^
SimpleGrayImage.h:86:2: note:   candidate expects 2 arguments, 1 provided
SimpleGrayImage.h:80:2: note: SimpleGrayImage::SimpleGrayImage()
  SimpleGrayImage();
  ^
SimpleGrayImage.h:80:2: note:   candidate expects 0 arguments, 1 provided

Upvotes: 0

Views: 90

Answers (1)

Raxvan
Raxvan

Reputation: 6505

From the errors i can see that the copy constructor is not defined correctly:

SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)

This will not be called since the value you return from function apply_mask is not local variable but an rvalue.

For the constructor to take rvalues you need to change the signature of the copy constructor to

SimpleGrayImage::SimpleGrayImage(const SimpleGrayImage&)//note the new const

Edit: For more information on rvalues you can check this link. Rvalues can be converted to const SimpleGrayImag& a = apply_mask() because the const ensures that you can't make changes to a so the compiler can safely give you the address of that local memory. The definition without const can only be used on lvalues like such:

SimpleGrayImag a;//this is an lvalue;
SimpleGrayImag b = a;

The best approach is to use const on all the arguments that you don't want them to be output arguments. Also you can make functions with both versions const and non const and most of the time the compiler will understands you, however it should be avoided because the code is harder to read and understand.

Upvotes: 3

Related Questions