开发者

int transforms into int&?

code snippet:

// some code
SDL_Surface* t = Display->render_text(text);
int z=100;
Display->blit_image(t,z,100);
// some more code

does not compile because z magically changes to an int&, file.cpp:48: error: no matching function for call to ‘display::blit_image(SDL_Surface*&, int&, int)

how can this happen?

post scriptum: the following works if i put them in place of Display->blit_image(t,z,100)

Display->blit_image(t,z,100,0);

but i am sure that th 4th param is optional because the exact same function works elsewhere without it

pps: i created a minimal-case of my code that behaves as describd above it's 3 files:

monkeycard.cpp: http://pastebin.com/pqVg2yDi

display.hpp: http://pastebin.com/xPKgWWbW

display.cpp: http://pastebin.com/nEfFX1wj

g++ -c 开发者_如何学编程display.cpp monkeycard.cpp fails with: monkeycard.cpp: In member function ‘void monkeycard::messagebox(std::string)’: monkeycard.cpp:28: error: no matching function for call to ‘display::blit_image(SDL_Surface*&, int&, int)’ display.hpp:26: note: candidates are: void display::blit_image(SDL_Surface*, int, int, SDL_Rect*)


The error message tells you what you're trying to pass. With automatic conversions and whatnot, that doesn't mean the function must have exactly that signature.

int& here just means that the parameter you've provided is an lvalue, and so it could be passed as a non-const reference. A function can match with that parameter as an int&, const int&, int, long, const float&, etc.

the point is that if instead of z i write 100 it works.

That's interesting. I can't immediately think of a way to write a function that accepts an integer literal, but not an integer variable. The following code compiles, of course:

struct SDL_Surface;
struct SDL_Rect;

struct display {
    void foo(SDL_Surface* img, int x=0, int y=0, SDL_Rect* clip=0) {}
};

int main() {
    display d;
    int z = 0;
    SDL_Surface *p = 0;
    d.foo(p,z,100);
}

So there must be something else you haven't mentioned yet, which causes the issue.

Edit: visitor and Charles Bailey (in a comment) have the answer. The defaults are missing from your declaration of the function, so as far as the compiler is concerned you are trying to call a 4-parameter function with 3 arguments. The & is not the problem.

For future reference: when James McNellis asked you for "the" declaration of your function, he meant the declaration which is visible in the translation unit making the call. In your pastebin code, the definition is not visible in that translation unit, and the compiler cannot reach in to a completely different .cpp file and realise that the function is supposed to have parameter defaults. In C++, default values are set up in the calling code, for reasons to do with how calling conventions work.


Having seen the code, the defaults should be given in the header and not in the implementation file.

When you are compiling "monkeycard.cpp", the compiler has only the information in the headers to work with. The compiler has no idea that blit_image has default arguments, and therefore cannot match the function to call.


I suspect that the function isn't declared properly.

There needs to be a prototype inside the class display scope such as:

void blit_image(SDL_Surface* img, int x=0, int y=0, SDL_Rect* clip=NULL);

When you pass an int & parameter (such as any named variable of type int) to an int argument, the value of the int & is copied into the new object of type int. The difference in types implies a conversion which entails a copy which implements pass-by-value. That is just how the C++ formalism works.


The error message you see is nothing else than a specific convention, which that particular compiler uses to generate error messages in cases like that. Apparently, when the compiler is unable to resolve a function call, it generates an error message where every Lvalue argument is reported as having reference type and every Rvalue argument is reported as having non-reference type. This makes some sense, since references in C++ exist specifically for implementing the concept of run-time-bound Lvalue. In fact, it might even turn out that this is exactly how the overload resolution is implemented internally in that compiler.

As for the reason for the error: the function you are trying to call does not exist (or exists, but has a non-matching set of parameters).

P.S. You said in the comments that the matching function actually does exist. That would mean that there's either a problem with the visibility of the function declaration, or a problem with the code you posted being "fake" (i.e. it is not the code you were actually compiling).


Primitives are not reference types in C++.

How do you know that it's the int& that's the cause for the error? The error simply says that the signature is in error. I'd recommend going back and checking the method signature to see what the root cause is.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜