143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
|||||||||||||||||||||
1 | |||||||||||||||||||||
Перенаправление указателя при перегрузке оператора в variadic template18.04.2015, 16:19. Показов 2351. Ответов 35
Метки нет (Все метки)
Есть вот такой вот код (сделан в vs2014):
Как видится всё это... Вот это должно по сути сработать... (пока что статически написан "0", в будущем конешно хотелось бы тоже поправить, чтоб можно было изменить, для этого int Cur хотел использовать)
И ещё, смежный вопрос, как в самом шаблоне проверить какой тип требуется и адрес. Т.е. хотелось бы чтоб в шаблоне можно было тоже следить за поведением переменных.
0
|
18.04.2015, 16:19 | |
Ответы с готовыми решениями:
35
Передача в метод по перегрузке оператора указателя на объект Ошибка при перегрузке оператора == Ошибка при перегрузке оператора << Ошибка при перегрузке оператора >> |
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
|
23.04.2015, 18:06 | 21 |
Да я понимаю, что не катит. Это демонстрация того почему не работает и что сделать, чтобы "работало".
Как ты определил, что он именно "понимает"? Покажи код, о котором ты говоришь, чтобы был предметный разговор. Знаешь, чтобы прояснить ситуацию, тебе надо задать другие вопросы. Например, тебе наверняка было бы полезно узнать как посмотреть какие именно типы попали в шаблон, чтобы разбираться по факту увиденного. а не по факту догадок. Интересно?
0
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
|
23.04.2015, 18:26 [ТС] | 22 |
Второй пример кода (какой там, 5 чтоли пост), где есть реальный double. Там работает функция atod, и аргументом так же посылается *char.
Ага, и поэтому в первой теме в ПС было написанно это: Очень! =)
0
|
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
||||||||||||||||||||||||||||||||||||
23.04.2015, 19:48 | 23 | |||||||||||||||||||||||||||||||||||
Эту формулировку можно воспринять по-разному. Она не столь однозначна, как тебе кажется. Ну да ладно, это не важно.
Вот код:
Это параметры самой функции call (выделил жирным куда смотреть) Повезло. Бинарно указатель и твой юнион совместимы, поэтому сработало. Если же необходимо из указателя получить значение для передачи в функцию (твой первый вопрос), то совпадением по памяти уже не отделаешься. Причем твой второй якобы работающий пример, все равно не работает, т.к. возвращает мусор, вместо 123.32. А все потому, что результат функции atof - double. Ты знаешь как возвращаются числа double в ассемблере? Если проще будет понять на примере, то вот код.
Реализация функций такая:
Для первой функции код, сгенерированный компилятором будет таким
Для второй функции код такой:
В твоем коде картина та же.
0
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
|
23.04.2015, 22:27 [ТС] | 24 |
оО "совпадение по памяти" это как будто "иголка в стоге сена", адрес в 4 байтах, начиная с v[1][3].d, само значение фиг знает где...
Да точно, хмм, странно, что то видимо я не посмотрел на это, увидел, вроде число и забил)) Откуда все эти ASM вообще ты берёш?.. и чё за FPU)) Добавлено через 10 минут *Я так понимаю ты меня склоняеш к тому что ассемблерные вставки мне помогут... Ну пойду читать)
0
|
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
|
23.04.2015, 23:22 | 25 |
Сообщение было отмечено Izual как решение
Решение
Юнион так устроен, что соответствует наиболее вместительному своему полю по размеру, адреса всех полей равны и равны адресу самой переменной юниона. Поэтому, если способ передачи параметра не различается (например как он различается в примере с double), то все равно какой был тип, главное, чтобы в первых его 4х байтах лежало то значение, которое ждет функция (в данном случае значение указателя). Проблемы начались бы, если бы у тебя был еще четвертый параметр, тогда в него попали бы остальные 4 байта твоего юниона (помним, что твой юнион 8 байт из-за double), а настоящий параметр затерялся. Я бы мог это продемонстрировать на примере кода, но все эти посты требуют большого количества времени, которого у меня нет. Если ты уделишь достаточное внимание обучению, то вскоре сам сможешь это делать без моей помощи.
Это дизассемблер примера на С++. Пример в том же посте. FPU Я тебя склоняю к тому, что твою задачу можно решать, только если хорошо представлять что происходит на уровне инструкций процессора. В одном из прошлых постов я тебе давал ссылку на библиотеку, где с помощью ассемблера добились того, что ты хочешь. Я утверждаю, что тебе либо придется повторить их путь, либо бросить эту затею.
1
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
|
23.04.2015, 23:31 [ТС] | 26 |
Ну значит будем штрудировать. =)
Жалко конешно что "просто из перегруженного оператора" нельзя сделать то что я хочу, ну значит есть куда стремиться ещё. Гора, Магомет уже идёт)))
0
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
|||||||||||||||||||||||||||||||||||||||||
26.04.2015, 16:43 [ТС] | 27 | ||||||||||||||||||||||||||||||||||||||||
DrOffset, да дизассембл интересная вещь... Жаль что твой пример, по крайней мере мне, сложно понять...
Собственно пока я тут копаюсь, накопалось оказывается, что без указания типа оператор double не срабатывает вообще. Т.е. на сколько я понял: С таким подходом:
Добавлено через 13 минут Ну и естественно из за этого сам шаблон уже по другому вопринимает данные. Без типа:
Добавлено через 7 минут Может есть обходной кстати вариант. Например меня одолевает мысль, что т.к. в принципе я имею в структуре уже известный тип, то можно было бы приводить аргументы в шаблоне. (static_cast'ом чтоль, это хоть и по коду займёт место, но зато это предполагаю будет эмулировать поведения для опр. типа, и тут уже я смогу и колдовать сразу с указателями, как в общем то я и хотел сделать с double) Добавлено через 17 часов 12 минут Оказалось что прототип функции в шаблоне действительно себя странно ведёт.
Лан, ушёл дальше ковыряться)
0
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
||||||||||||||||||||||||||
28.04.2015, 21:39 [ТС] | 28 | |||||||||||||||||||||||||
Перегруженный оператор uniona не дал в итоге мне возможность возвращять разные типы значений.
Может ли функция вернуть разный тип? Читал про перегрузку функций и шаблоны, но ни то ни другое пока не нашёл как применить в виду следующих причин: 1. Перегруженная функция обязана иметь разные типы или кол-во аргументов. А у меня аргумент всегда один (структура). 2. Шаблонная функция требует статически написать тип, например:
Подразумевается:
Использовать хочу для вызова своей функции:
0
|
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
|
|
28.04.2015, 22:27 | 29 |
Если "соответствие числу" определяется на этапе исполнения программы, то шаблоны и перегрузка не помогут, т.к. это статический полиморфизм, т.е. здесь например
тип T должен быть определён до исполнения программы.
0
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
|
28.04.2015, 22:34 [ТС] | 30 |
Надо в runtime...
Добавлено через 1 минуту А что может помочь? (я конешно уже получил вариант с dyncall от offseta, но сторонняя библиотека..)
0
|
What a waste!
1608 / 1300 / 180
Регистрация: 21.04.2012
Сообщений: 2,729
|
|
28.04.2015, 22:44 | 31 |
Сотню раз наверное уже писали, но в рамках языка С++ этого неосуществимо.
Добавлено через 3 минуты Динамический полиморфизм (т.е. типы определяются в runtime), в С++ это в любом случае сводиться к иерархии классов с виртуальными методами. Добавлено через 4 минуты Либо некий обобщённый handle на ресурс и много switch-ей и cast-ов везде, где нужно знать тип объекта.
0
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
||||||
28.04.2015, 22:58 [ТС] | 32 | |||||
Хотя бы так, но в рамках того что функция может требовать разное кол-во членов, хотелось бы чтоб был некий обобщённый вариант возврата.
типа:
Если можно было бы создать одну функцию (с ~20 case под кол-во типов), в чём собственно и вопрос)
0
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
|
01.05.2015, 08:11 [ТС] | 33 |
Ты же наверно не случайно мне привёл этот пример... Хотелось бы пояснений..))
Я так предполагаю, что дело происходит так: Ляляля, вызывается функция atod, наверно неважно как туда попали данные, сама функция сделает всё правильно не зависимо от того, union ли туда передали или нет и возвратит тоже правильно, но уже из возвращяемого значения (из стека наверно) будет произведена конвертация в тип union, а тут уже "как получится" (предполагаю что вернуло по инструкции long long(8 байт же), ведь для каждого типа свои блоки памяти для опр. перечней данных, ну типа где знак, где целая часть, где дробная и т.д.) В общем, используя ассемблер можно ли подменить тип возврата? Или может можно извлечь "не правильно скомпанованные данные" и поменять что то(в каких то регистрах) местами по нужной конструкции double, и будет как надо?...
0
|
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
||||||
02.05.2015, 17:44 | 34 | |||||
Izual, не очень понятно что ты хочешь.
Но сразу скажу что сделать нельзя. Нельзя динамически, имея только указатель на функцию, узнать каким именно образом она возвращает данные. Через регистры общего назначения, FPU или еще как. Это можно сделать, только заранее зная прототип этой функции и правильную конвенцию вызова. И это касается не только С++ . Я так понимаю это вот к этому вопрос: Если так, то в целом это можно сделать. Даже без ассемблера.
Вторая задача, еще более сложная. Нужно сделать так, чтобы на основе информации времени исполнения, сохраненной в нашем вариантном типе (это информация о том, какой там тип на самом деле), сгенерировался правильный вызов некой процедуры. От процедуры у нас есть только адрес, ну и конвенция вызова (если это вызовы win api, то она известна и едина для всех них). Вот это решить средствами С++ на 100% нельзя. И код, который будет осуществлять вызов нашей процедуры придется генерировать динамически прямо в памяти, а потом отдавать ему управление. Естественно, если процедура на самом деле имеет другие параметры или другую конвенцию вызова, мы, при таком подходе, становимся никак не защищены от падений и других спецэффектов. Т.е. все на наш страх и риск. Т.е. вторая задача потребует от тебя написать маленький компилятор внутри своей программы, который будет прямо в памяти делать код для вызова исходя из динамической информации о типе, сохраненном в variant. Есть готовые реализации таких вещей, у некоторых компиляторов есть api для JIT генерации кода, есть еще вот такая библиотека. Но если ты все-таки собрался все-все делать сам, приготовься к тому, что изучать придется очень много, и поверхностным ознакомлением не обойтись.
0
|
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
|
|||||||||||
05.05.2015, 11:07 [ТС] | 35 | ||||||||||
Хочу использовать функции из DLL'ок. Пока что все примеры с гугла провальны, все они требуют либо статически писать типы(к чему мы в общем то подошли) либо статически описывать прототипы функции, просто потому что из DLLки "нормальный" прототип не вытаскивается =(
Я потому и спросил в предыдущем посте, можно ли выцедить данные из стека, которые возвращет функция. Опять же статически всё, тоже самое что я буду в скобках писать тип для подачи в ф. call Полиморфизм даёт dynamic_cast, но он один фиг мне вернёт тип класса, а не базовый(char,int,float,double). Да и виртуальная функция не подойдёт, т.к. мне надо разный тип получать, а вирт. функции возвращяют всё по одному прототипу. Шаблон дал лиш часть, как видно, но не всё что надо... Сам же знаеш) Потому топик и висит, что ответа "как сделать чтоб работало" ещё небыло, (кроме dyncall, но как то сторонней библиотекой неизвестной пользоваться не хочется, да и честно говоря по ней инфы мало), даже блин вектора движения ещё не предложили. =( Ну с таким же успехом можно сказать, что может вырубиться электричество)) Типы то есть, только они в string виде, а string в тип не конвертится) Есть пример? Или "чё почитать"?)) Не проблема, если это стоит того... Добавлено через 1 час 55 минут Сижу пока асм изучаю, пытаюсь свою теорию по поводу стэка подтвердить... Нашёл вот что:
0
|
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,284
|
|
05.05.2015, 13:33 | 36 |
Во-первых не из стека, а из регистра ax. Команда imul сохраняет результат в ax, и, согласно calling convention для x86, целые числа как раз возвращаются через ax. Т.е. фактически return здесь есть.
В зависимости от типа возврата, результат может быть в регистре (или регистрах) общего назначения, в специальных регистрах, на стеке. В регистре может быть как значение, так и адрес стековой памяти, где лежит большой объект. В общем виде нельзя, имея лишь адрес функции, сказать, каким именно способом она вернет значение. Вот немного материала по теме. Ключевые слова для поиска "generating function calls dynamically". На данном этапе я сомневаюсь, что кто-то сможет предложить то, что тебе подойдет сразу. Я тебе предлагаю учиться. В данной ситуации, на мой взгляд, это лучше всего. Чтобы постичь сложные технические решения - надо учиться. Так уж вышло, что тема, которую ты затронул, не относится к разряду тривиальных. И по еще одному совпадению она не относится к разряду жизненно необходимых индустрии (проще говоря, это практически никому не нужно). Поэтому с одной стороны, информации очень мало в свободном доступе, т.к. этими вопросами занимаются единицы, с другой стороны, решения, которые уже есть, требуют высокой квалификации, чтобы их понять. Нужно под другим углом смотреть на задачу. Ты смотришь не под тем. То, что возвращает виртуальная функция в данной задаче вообще не интересно. Тут другие ее особенности используются. В любом случае ради примера писать тебе вариантный тип я не стану. Это трудоемко, и я сомневаюсь, что ты сможешь оценить мои старания. Т.к. сразу вникнуть в сложный код не получится, а долго разбираться в чужом коде ты не любишь Уж не обижайся.
0
|
05.05.2015, 13:33 | |
05.05.2015, 13:33 | |
Помогаю со студенческими работами здесь
36
Ошибки при перегрузке оператора << Предупреждение при перегрузке оператора Ошибка при перегрузке оператора + Variadic template Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |