Всем привет.
уже неделю мучает один вопрос есть макрос
(тем 20 до этой есть мой вопрос об этом же но более развернуто)
#define zoo(e,...) \
blabla<typeof(e)>(__VA_ARGS__)
в него передается список парметров
и имя перегруженной функции
как подходящий тип функции вывести ?
например имеем
strstr(char*,const char*);
strstr(const char*,const char*);
вот вызывем макрос так к примеру
char *pp = 0;
const char *cc = 0;
zoo(strstr, pp, cc);
нужно в макросе получить тип char*(char*,const char*);
невозможно подставить boost_typeof ругается
на то что незнает тип какой именно из пергруженных
функций нужен а указать ему какие
аргументы прилагаются никак не выходит
ну чтоб он вывел точный тип исходя из аргументов
как такое сделать ?
Здравствуйте, jyuyjiyuijyu, Вы писали: J>ну чтоб он вывел точный тип исходя из аргументов J>как такое сделать ?
Все решаемо
В общих чертах идея проста.
Нам нужна функция, которая может принять указатель на функцию и возвратить указатель на функцию, но где нам достаточно будет указать типы аргументов, а возвращаемый тип выведется сам:
Пояснение:
Имя функции будет check.
Имя параметра функции будет f.
Тип у f: R (*)(T1, T2)
Возвращаемый тип у check: R (*)(T1, T2)
Такой изврат необходим, чтобы компилятор мог вывести тип R автоматически.
Теперь положим мы имеем функции:
void ff(int, char){}
void ff(long, long){}
int ff(int, void*){return 0;}
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Всем привет. J>уже неделю мучает один вопрос есть макрос J>(тем 20 до этой есть мой вопрос об этом же но более развернуто) J>... J>вот вызывем макрос так к примеру J>... J>невозможно подставить boost_typeof ругается J>на то что незнает тип какой именно из пергруженных J>функций нужен а указать ему какие J>аргументы прилагаются никак не выходит J>ну чтоб он вывел точный тип исходя из аргументов J>как такое сделать ?
блин, твое разбиение строк и пунктуация взрывает мне мозг
Здравствуйте, _nn_, Вы писали:
...
template<typename T1, typename T2, typename R>
R (*check (R (__cdecl*f)(T1, T2))) (T1, T2)
{
return f;
}
template<typename T1, typename T2, typename R>
R (__stdcall*check (R (__stdcall*f)(T1, T2))) (T1, T2)
{
return f;
}
спасибо за внимание проверил я Ваш код
обнаружил вот какую проблему
допустим имеем такую функу
void fi(char*,char*){}
вот...
допустим вызов такой
#define zoo(e,...) \
blabla<remove_pointer<typeof(check<UNPACK_TYPE(__VA_ARGS__)>(e))>::type>(__VA_ARGS__)
...
zoo(fi,0,"");
...
ну или любой другой тип ожидаемого указателя вместо которого передается 0
подставляем список типов из __VA_ARGS__ в check
получается
check<int,const char*>(fi)
в итоге check раскрывается в
template<int, const char*, void>
void (*check (void (*f)(int, const char*))) (int, const char*)
{
return f;
}
и происходит конфликт ожидаемого void(*)(int,const char*)
с по факту переданным void(*)(char*,char*)
придется вместо 0 для нулевых указателей
всегда передавать реальную переменную указатель
или на месте делать кастинг zoo(fi, (char*)0, "")
а так да проблема решается и с calling convention и с
overloaded function но это недопустимо
придется весь существющий код править где передается 0 вместо нулевого указателя
да и новый писать так не удобно (не стандартно)
вот просто когда юзаем функции
strstr(char*,const char*);
strstr(const char*,const char*);
...
char *pp = 0;
const char *cc = 0;
strstr(pp,cc);
strstr(cc,cc);
компилятор быстро находит нужную
перегруженную версию и знает полный тип ret_t calling_t(arg1_t, и т.д.)
у нас есть аргументы и имя функции
надо просто указать компилятору найти все перегрузки
сопоставить и вернуть тип если что то подошло
но как это правильно спросить у компилятора
великая тайна по видимому
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>вот просто когда юзаем функции J>strstr(char*,const char*); J>strstr(const char*,const char*); J>... J>char *pp = 0; J>const char *cc = 0; J>strstr(pp,cc); J>strstr(cc,cc); J>компилятор быстро находит нужную J>перегруженную версию и знает полный тип ret_t calling_t(arg1_t, и т.д.)
Он находит , так как вы передаете ему правильные типы.
А попробуйте передать неправильные то сразу будет проблема:
strstr(0, 0);
ambiguous call to overloaded function
J>у нас есть аргументы и имя функции J>надо просто указать компилятору найти все перегрузки J>сопоставить и вернуть тип если что то подошло J>но как это правильно спросить у компилятора J>великая тайна по видимому
Тут сложнее чем вы пишете.
Вы хотите найти все функции где есть возможность конвертации типов, а не точное сопоставление типов.
Т.е. имея
void f(char* , char*)
вы хотите получить эту функцию имея два аргумента 0,0.
Эти два аргумента имеют типы int, int.
Но в случае нуля они могут стать и char*.
Теперь, BOOST_TYPEOF(0) нам даст int и никогда не даст ничего другого.
А нам нужно в компайл тайм проверить что это 0, а потом удостовериться ,что функцию принимает указатель и сказать что типы совместимы.
При этом все равно будут неоднозначности.
Вот в случае strstr, вызов BOOST_TYPEOF(strstr(0,0)) что должен дать ? 1-ю или 2-ю версию ?
Здравствуйте, _nn_, Вы писали:
__>Здравствуйте, jyuyjiyuijyu, Вы писали:
J>>вот просто когда юзаем функции J>>strstr(char*,const char*); J>>strstr(const char*,const char*); J>>... J>>char *pp = 0; J>>const char *cc = 0; J>>strstr(pp,cc); J>>strstr(cc,cc); J>>компилятор быстро находит нужную J>>перегруженную версию и знает полный тип ret_t calling_t(arg1_t, и т.д.) __>Он находит , так как вы передаете ему правильные типы. __>А попробуйте передать неправильные то сразу будет проблема: __>
strstr(0, 0);
__>
__> ambiguous call to overloaded function
J>>у нас есть аргументы и имя функции J>>надо просто указать компилятору найти все перегрузки J>>сопоставить и вернуть тип если что то подошло J>>но как это правильно спросить у компилятора J>>великая тайна по видимому __>Тут сложнее чем вы пишете. __>Вы хотите найти все функции где есть возможность конвертации типов, а не точное сопоставление типов.
нет я хочу узнать тип после того как компилятор определит есть ли подходящая функция
и если нет неоднозначности тоесть так как он всегда делает __>Т.е. имея __>void f(char* , char*) __>вы хотите получить эту функцию имея два аргумента 0,0. __>Эти два аргумента имеют типы int, int. __>Но в случае нуля они могут стать и char*.
вот если переданы нули и если можно вызвать f то он должен дать ее тип
так как бы поступил он если бы вызвал то пусть вернет тип или ошибку
__>Теперь, BOOST_TYPEOF(0) нам даст int и никогда не даст ничего другого. __>А нам нужно в компайл тайм проверить что это 0, а потом удостовериться ,что функцию принимает указатель и сказать что типы совместимы.
__>При этом все равно будут неоднозначности. __>Вот в случае strstr, вызов BOOST_TYPEOF(strstr(0,0)) что должен дать ? 1-ю или 2-ю версию ?
это и в обычной жизни ошибка я говорю про законные варианты например
0 для strstr может быть только вторым и если передают
char *p = 0;
const char *pp = 0;
macro(strstr,p,0);
или
macro(strstr,pp,0);
я хочу узнать какой тип выберет компилятор
задача звучит предельно просто узнать точный тип перегруженной функции
имея на руках ее имя и аргументы к ней
и ничего немогу придумать как только не пытался
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Всем привет. J>уже неделю мучает один вопрос есть макрос J>(тем 20 до этой есть мой вопрос об этом же но более развернуто) J>#define zoo(e,...) \ J>blabla<typeof(e)>(__VA_ARGS__) J>в него передается список парметров J>и имя перегруженной функции J>как подходящий тип функции вывести ? J>например имеем J>strstr(char*,const char*); J>strstr(const char*,const char*); J>вот вызывем макрос так к примеру J>char *pp = 0; J>const char *cc = 0; J>zoo(strstr, pp, cc); J>нужно в макросе получить тип char*(char*,const char*);
Концепция несколько странная: получается, для того, чтобы вывести тип формальных параметров, необходимо сконструировать объекты всех фактических. А если функция принимает какой-то "тяжелый" тип? Пусть даже по ссылке — все равно его придется создать — и только лишь для того, чтобы просто вывести тип?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, jyuyjiyuijyu, Вы писали:
J>>Всем привет. J>>уже неделю мучает один вопрос есть макрос J>>(тем 20 до этой есть мой вопрос об этом же но более развернуто) J>>#define zoo(e,...) \ J>>blabla<typeof(e)>(__VA_ARGS__) J>>в него передается список парметров J>>и имя перегруженной функции J>>как подходящий тип функции вывести ? J>>например имеем J>>strstr(char*,const char*); J>>strstr(const char*,const char*); J>>вот вызывем макрос так к примеру J>>char *pp = 0; J>>const char *cc = 0; J>>zoo(strstr, pp, cc); J>>нужно в макросе получить тип char*(char*,const char*);
R>Концепция несколько странная: получается, для того, чтобы вывести тип формальных параметров, необходимо сконструировать объекты всех фактических. А если функция принимает какой-то "тяжелый" тип? Пусть даже по ссылке — все равно его придется создать — и только лишь для того, чтобы просто вывести тип?
нет тип не выводится просто так он используется вместе с аргументами в дальнейшем