2010-09-06 4 views
0

фрагмент кода:int преобразуется в int &?

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

не компилируется, поскольку г волшебно меняется на INT &, file.cpp: 48: ошибка: нет функции соответствия для вызова «дисплей :: blit_image (SDL_Surface * &, внутр &, int)

как это может случиться?

Постскриптум: следующие работы, если я положил их на место Экран-> blit_image (т, г, 100)

Экран-> blit_image (т, г, 100,0);

, но я уверен, что го 4 парам не является обязательным, так как та же самая функция работает в другом месте без него

бод: я создал минимальный-случай моего кода, который ведет себя, как describd выше это 3 файла:

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

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

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

г ++ -c display.cpp monkeycard.cpp терпит неудачу с: monkeycard.cpp: В функции члена Пустота monkeycard :: MessageBox (станд :: строка) ': monkeycard.cpp: 28: ошибка: нет соответствия функции звоните в 'дисплей :: blit_image (SDL_Surface * &, внутр &, целое)' display.hpp: 26: Примечание: кандидаты: аннулируются дисплей :: blit_image (SDL_Surface *, Int, Int, SDL_Rect *)

+1

Как произносится 'blit_image'? –

+0

void display :: blit_image (SDL_Surface * img, int x = 0, int y = 0, SDL_Rect * clip = NULL) { // код – lorb

+0

Отображается ли 'Display-> blit_image (t, int (z), 100); 'работа? – fredoverflow

ответ

3

После просмотра кода значения по умолчанию должны указываться в заголовке, а не в файле реализации.

Когда вы компилируете «monkeycard.cpp», компилятор имеет только информацию в заголовках для работы. Компилятор не знает, что blit_image имеет аргументы по умолчанию и поэтому не может соответствовать функции для вызова.

0

Примитивы не являются ссылочными типами в C++.

Откуда вы знаете, что это int&, что является причиной ошибки? Ошибка просто говорит, что подпись ошибочна. Я бы рекомендовал вернуться и проверить подпись метода, чтобы узнать, в чем причина.

+0

Дело в том, что если вместо z пишу 100, это сработает. – lorb

4

Сообщение об ошибке сообщает вам, что вы пытаетесь передать. С автоматическими преобразованиями и еще много чего, это не означает, что функция должна иметь именно эту подпись.

int& здесь просто означает, что параметр вы предоставили именующий, и поэтому он мог быть принят в качестве неконстантной ссылки. Функция может соответствовать этому параметру как int&, const int&, int, long, const float& и т.д.

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

Это интересно. Я не могу сразу придумать способ написать функцию, которая принимает целочисленный литерал, но не целочисленную переменную. Следующий код компилируется, конечно:

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

Так что должно быть что-то еще вы еще не упоминали, что вызывает проблему.

Редактировать: посетитель и Чарльз Бейли (в комментарии) имеют ответ.Значения по умолчанию отсутствуют в объявлении функции, так что, насколько это касается компилятора, вы пытаетесь вызвать 4-параметрическую функцию с тремя аргументами. & не проблема.

Для справок в будущем: когда Джеймс Макнеллис попросил вас «объявление» вашей функции, он имел в виду декларацию, которая видна в блоке перевода, выполняющем вызов. В вашем коде pastebin определение не отображается в этой единицы перевода, и компилятор не может дотянуться до совершенно другого .cpp-файла и понять, что функция должна иметь параметры по умолчанию. В C++ значения по умолчанию настраиваются в вызывающем коде, чтобы определить, как работают соглашения о вызовах.

+0

Я не следую. i определил blit_image, чтобы взять указатель на SDL_Surface и после этого опционально два ints (и указатель на SDL_Rect). Я предоставил ему первый и два ints, но он жалуется, что z является int & в строке 48, где строка 47 говорит: int z = 100; – lorb

+0

@lorb: 'int &' vs 'int' - это обозначение, которое gcc использует, чтобы отличить аргумент lvalue (z) от аргумента rvalue (100). Это не означает, что компилятор считает, что вы действительно объявили 'int & z = something'. –

+0

@Steve: Если вы объявляете 'z' как' int & ', выражение *' '' все еще имеет тип 'int', * not *' int & '. См. Пункт 5 раздела 5 ISO03 – fredoverflow

1

Я подозреваю, что функция не объявлена ​​должным образом.

Там должен быть прототипом внутри class display сферы, такие как:

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

При передаче int & параметра (например, какими-либо имя переменного типа int) к int аргументу, значения int & копируется в новый объект типа int. Разница в типах подразумевает преобразование, которое влечет за собой копию, которая реализует pass-by-value. Именно так работает формализм C++.

1

Сообщение об ошибке, которое вы видите, является не чем иным, как конкретным соглашением, которое этот конкретный компилятор использует для генерации сообщений об ошибках в подобных случаях. По-видимому, когда компилятор не может разрешить вызов функции, он генерирует сообщение об ошибке, в котором сообщается, что каждый аргумент Lvalue имеет ссылочный тип, и каждый аргумент Rvalue сообщается как имеющий тип без ссылки. Это имеет смысл, поскольку ссылки на C++ существуют специально для реализации концепции Lvalue, связанной со временем выполнения. На самом деле, возможно, даже окажется, что именно так во внутреннем контексте в компиляторе реализовано разрешение перегрузки.

Что касается причины ошибки: функция, которую вы пытаетесь вызвать, не существует (или существует, но имеет несогласованный набор параметров).

P.S. Вы сказали в комментариях, что функция соответствия действительно существует. Это будет означать, что существует проблема с видимостью объявления функции или проблема с кодом, который вы опубликовали, «поддельным» (т. Е. Это не тот код, который вы на самом деле компилировали).

Смежные вопросы