c++, указатель на нестатическую функцию класса,

Irina22

значит объявлена функция вот так:
 int submult (double *matrix, int (*el_funcint, int,int,intint x, int y,int xk, int yk); 

где el_func - указатель на функцию должен быть.

int godmat::el(int x, int y, int i, int j)
{
return 0;
}

теперь вызываю
 	submult(a,&el,x,zj,k,k); 

все функции в одном классе.
msvs2003 ругается:
'&' illegal operation on bound member function expression
где я ошибся?

Chupa

& не нужен

Irina22

да я уж попробовал

cannot convert parametr 2 from *int (int,int,int,in) to int (__cdecl*int,int,int,int)
что за __cdecl* - я, вообще говоря, не знаю

RED-GREEN

submult(a,&godmat::el,x,zj,k,k); ?

Irina22

submult(a,&godmat::el,x,zj,k,k);
cannot convert parametr 2 from *int(__thiscall godmat::*) (int,int,int,in) to int (__cdecl*int,int,int,int)
submult(a,&(this->elx,zj,k,k);
'&' illegal operation on bound member function expression

Marinavo_0507

static int godmat::el(int x, int y, int i, int j)
?

RED-GREEN

int submult (int matrix, int (*el_funcint, int,int,intint x, int y,int xk, int yk);
class godmat
{
public:
static int godmat::el(int x, int y, int i, int j);
};
int godmat::el(int x, int y, int i, int j){ return 0;}
int main
{
int a,x,zj,k;
submult(a,&gotmat::el,x,zj,k,k);
return 0;
}

Irina22

я думал об этом,
только она использует некоторые нестатичные переменные класса, а это, вроде static-функция не должна делать
со статиком всё работает...
вернее осталась ошибка о доступе к non-static member

Marinavo_0507

> только она использует некоторые нестатичные переменные класса
тады ой

Irina22

а что нельзя передать указатель на нестатичную функцию каким-то образом?

Irina22

это глюк компилятора или в принципе такого делать нельзя?

alexkravchuk

вроде нет... Только через указатель на класс...

RED-GREEN

ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&godmat::el'

Irina22

жаль.
всем спасибо.

alexkravchuk

что-то не понял. Я имел в виду, что в параметрах функции запрашивать не указатель на функцию, а указатель на класс. В противном случае, так как функция-член на низком уровне получает ещё и указатель на класс, компилятор не сможет определить по коду характеристики этого класса, где в нём хранятся переменные и т.п.

mira-bella

Уж извините, плиз, мою язвительность.
Но если бы вы хоть немного понимали язык C++ вам бы не пришло в голову задать такой идиотский вопрос.
Надеюсь к этому моменту вы уже осознали всепоглощающую глупость своего вопроса, а если нет, то я могу вам объяснить вашу ошибку, если хотите. Глядишь знаний языка чуть прибавиться.

Marinavo_0507

> Но если бы вы хоть немного понимали язык C++
> вам бы не пришло в голову задать такой идиотский вопрос.
Если немного понимать не только C++, но и что-нибудь ещё, то тут же придёт в голову мысль, что компилятор вполне мог бы и автоматически сгенерировать трамплин, чтоб получить необходимый closure. Вот вовремя его уничтожить - это уже более серьёзная проблема.

mira-bella

Если немного понимать не только C++, но и что-нибудь ещё, то тут же придёт в голову мысль, что компилятор вполне мог бы и автоматически сгенерировать трамплин, чтоб получить необходимый closure. Вот вовремя его уничтожить - это уже более серьёзная проблема.
эээ
не понял какое все это имеет отношение к первоначальному вопросу
Какой смысл вы вкладываете в термин "трамплин", "closure"?

alexkravchuk

Я думаю смысл заключается в том, что вопрос не настолько очевиден, чтобы так говорить... Да и вообще, хочетшь опустить - пиши в ПМ, на публике это делать неприлично просто.
А вообще, можно было бы (с точки зрения разработчиков языка) примерно так реализовать.
Допустим, компилятор видит, что функция использует не нормальную функцию, а функцию-член. Тогда он добавляет некоторый невидимый параметр, указатель на данные класса, и уже вызывает функцию в соответствии с этим. Другое дело, что в таком варианте функции должны определяться по-разному. Но определённую прозрачность сделать можно, подобно тому, как существует прозрачность относительно виртуальных и обычных функций. А если пожертвовать производительностью - то можно сделать полную прозрачность, или если не исходить из соображений, что функция может быть уже откомпилирована, и правка её невозможна.

mira-bella

а что нельзя передать указатель на нестатичную функцию каким-то образом?
это сделать можно, но уж конечно не так как указано в вашем примере.
Нестатичная функция-член класса имеет другой тип нежели обычная функция не член (или статическая функция-член, что вобще-то почти тоже самое) с таким же набором аргументов и возвращаемым значением, поскольку у нестатичной функции-члена есть еще один неявный "нулевой" аргумент this - указатель на объект класса, который явно указывается при ее вызове перед оператором "." или "->". И именно об этом вам говорит мелкомягкий компилятор, когда пишет "cannot convert...".

mira-bella

Тогда он добавляет некоторый невидимый параметр, указатель на данные класса, и уже вызывает функцию в соответствии с этим. Другое дело, что в таком варианте функции должны определяться по-разному.
представляете в C++ и так уже есть функции, к которым добавляется "невидимый параметр" в виде указателя на объект класса - это нестатические функции-члены данного класса. Думаю подробнее раскрывать эту тему надобности нет.
или если не исходить из соображений, что функция может быть уже откомпилирована, и правка её невозможна.
а из этого надо всегда исходить
функция вообще может быть определена в другой трансляции и являтся внешним идентификатором.

ppplva

Вот только этот невидимый параметр не входит в указатель на такую функцию. О чем и шла речь.

mira-bella

Вот только этот невидимый параметр не входит в указатель на такую функцию. О чем и шла речь.
Конечно не входит.
Ну и? К чему это сказано?
Этот "невидимый параметр" (указатель на объект класса) функции-члена при вызове этой функции либо явно указывается слева от оператора "." или "->", либо подразумевается this, если вызов происходит из функции-члена класса, ссылка на который конвертится в ссылку на тип класса, членом которого является вызываемая функция (т.е. если класс вызывающей функции-члена наследует класс вызываемой функции-члена или они совпадают поэтому как ни крути этот "невидимый параметр" при правильном вызове функции-члена всегда определен и он не должен никуда "входить".
А если вы это сказали как бы в качестве объяснения или ответа на изначальный вопрос автора треда, так это и ежу понятно.
Причина по которой нельзя использовать функцию-член вместо простой функции в качестве параметра некой функции (как и во всех остальных выражениях) очевидна: типы этих функций разные, потому что хотя с виду у них параметры одинаковые на самом деле это не так, ибо у функции-члена есть "нулевой" параметр - ссылка на объект (который явно или неявно передается при вызове а у обычной функции его нет, поэтому типы этих функций несовместимы (ибо их вызов происходит по-разному).

Julie16

нет, не мог бы. Так как этот closure еще куда-то положить надо. А куда его положить - компилятор понятия не имеет. конечно его можно положить куда-то, но тогда это будет не thread safe.
PS: стандартное решение - завести функцию с дополнительным параметром:
int global_el( godmat* _this, int x, int y, int i, int j )
{
return _this->el( x, y, i, j );
}
и передавать в submult именно ее + указатель на объект класса godmat. А еще лучше завести себе интерфейс и передавать в submit объект класса, удовлетворяющий этому интерфейсу.

Marinavo_0507

> А куда его положить - компилятор понятия не имеет.
Ну это конечно не так, но чудак со значком (I) рядом с ником всё равно не должен прочитать ответ.

Julie16

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

Marinavo_0507

ну ты почитай, что такое трамплин
в "ненатуральских" языках они как раз и не нужны

kentavr

Указатель на функцию можно объявить и использовать следующим образом.
 class prostoclass
{
public:
int func(float);
};
////
int (prostoclass::*pmemfuncfloat);
pmemfunc = &prostoclass::func;
prostoclass ob;
(ob.*pmemfunc2.2);

Тут мембер функция используя свой указатель вызывается ЧЕРЕЗ ОБЪЕКТ. Запомните, что указатель на функцию ничто без объекта. Без объекта с ним ничего разумного сделать нельзя.
Оставить комментарий
Имя или ник:
Комментарий: