Форум программистов, компьютерный форум CyberForum.ru

Перенаправление указателя при перегрузке оператора в variadic template - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Голосовое управление. Активация записи http://www.cyberforum.ru/cpp/thread1424001.html
Здравствуйте! Хочу добавить в свой проект умного дома голосовое управление. Нужно несколько команд - включить свет/выключить свет/открыть жалюзи и т.д. С распознаванием команды проблем быть не должно, распознавать можно через гугл или яндекс. Вопрос в том, как активировать распознавание? У меня пока что только такая мысль: при появлении звука в микрофоне записывать его, а после окончания...
C++ RAW сокет нужен рабочий пример создания сырого сокета З.ы под windows Добавлено через 20 минут нашел такой код, под хрюшей работает збс, но в 7 неработает, как можно это исправить? и можно ли это исправить вообще? #include <Winsock2.h>//Ws2_32.lib #include <ws2tcpip.h> //#include <Windows.h> #include <iostream.h> http://www.cyberforum.ru/cpp/thread1423999.html
Молодой поэт и программирование C++
Всем доброго времени суток!!!! Я на форуме первый день надеюсь, что мне помогут или дадут хороший совет. Мне надо написать программу или что-то вроде нее, которая решает мою проблему. Я почти всю свою жизнь пишу стихи. Но стихи эти непростые. Они написаны строчными буквами и без знаков препинания(нет ни точек, ни тире,ни запятых). Когда я печатаю текст то пишу сначала как надо для читателя, а...
ГОСТ для C++ C++
Ребят как правильно оформлять код программы, по какому госту?!
C++ Настройка Oracle Solaris Studio под Windows http://www.cyberforum.ru/cpp/thread1421315.html
скачал Oracle Solaris Studio но похоже она только для Solaris, OpenSolaris, Linux - есть ли возможность её Microsoft Windows ?
C++ Построить таблицу, содержащую проценты голосов, отданных командам Помогите пожалуйста, не могу запустить. Выбивает постоянно ошибку при запуске и не могу понять почему. Вот условие: В спортивных соревнованиях участвуют n команд. В файле SPORT содержатся прогнозы результатов соревнований. Каждый прогноз включает номер команды, занявшей первое место, номер команды, занявшей последнее место, номера команд, входящих в первую тройку сильнейших команд.... подробнее

Показать сообщение отдельно
DrOffset
6801 / 4012 / 922
Регистрация: 30.01.2014
Сообщений: 6,835
23.04.2015, 19:48     Перенаправление указателя при перегрузке оператора в variadic template
Цитата Сообщение от Izual Посмотреть сообщение
Ага, и поэтому в первой теме в ПС было написанно это:
Эту формулировку можно воспринять по-разному. Она не столь однозначна, как тебе кажется. Ну да ладно, это не важно.
Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <typename T>
void print_t()
{
    printf("\n%s\n", __FUNCSIG__);
}
 
template <typename Result, typename... Args>
void call(void * fun, Result& r, Args ... args)
{
    print_t<decltype(call<Result, Args...>)>();
 
    using func_type = Result(_cdecl *)(Args...); // прототип функции
 
    print_t<func_type>();
 
    r = ((func_type)fun) (args...); // вызов функции
}
Строка, которую будет выводить функция print_t, будет содержать в том числе и типы параметров, которые попали в шаблон. Для твоего примера, например, будут такие строки
Это параметры самой функции call (выделил жирным куда смотреть)
void __cdecl print_t<void(void *,union var::<unnamed-type-d> &,union var::<unnamed-type-d>)>(void)
А это прототипа, к которому функция call приводит свой первый параметр:
void __cdecl print_t<unionvar::<unnamed-type-d>(__cdecl *)(union var::<unnamed-type-d>)>(void)
Как видно, получившаяся функция возвращает анонимный юнион и принимает такой же юнион в качестве параметра. Что в точности соответствует тому, что мы писали тебе ранее.

Цитата Сообщение от Izual Посмотреть сообщение
Там работает функция atod, и аргументом так же посылается *char.
Повезло. Бинарно указатель и твой юнион совместимы, поэтому сработало. Если же необходимо из указателя получить значение для передачи в функцию (твой первый вопрос), то совпадением по памяти уже не отделаешься.

Причем твой второй якобы работающий пример, все равно не работает, т.к. возвращает мусор, вместо 123.32. А все потому, что результат функции atof - double. Ты знаешь как возвращаются числа double в ассемблере?
Если проще будет понять на примере, то вот код.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
union test
{
    void * p;
    double d;
};
 
extern "C" double foo1();
extern "C" double foo2();
 
int main()
{
    double f1 = foo1();
    double f2 = foo2();
 
    printf("%lf %lf", f1, f2); //результаты отличаются!
}
Есть две функции, foo1() возвращает в результате обычный double. foo2() эмулирует то, что происходит у тебя.
Реализация функций такая:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
double f = 3.14;
// Функция возвращает double и компилятор знает об этом
extern "C" double foo1()
{
    return f;
}
 
extern "C" double foo2()
{
    // Насильно приведенная функция, теперь компилятор думает, что функция возвращает union test
    test (*fp)() = (test(*)())foo1;
    return fp().d;
}
Итак, результат первой функция напечатает 3.14. Вторая напечатает ноль или что-то невразумительное, не суть. Почему? Потому что ты ввел компилятор в заблуждение. Т.к. double и некий блок памяти 8 байт (наш юнион) возвращаются разными способами.
Для первой функции код, сгенерированный компилятором будет таким
Assembler
1
2
3
_foo1:
    fld QWORD PTR _f
    ret
И это правильный код. Компилятор знает, что функция возвращает double и генерирует оптимальный код для этого. Возвращается значение через стек FPU.
Для второй функции код такой:
Assembler
1
2
3
4
5
6
7
8
_foo2:
    sub esp, 12
    call    _foo1
    mov DWORD PTR [esp], eax
    mov DWORD PTR [esp+4], edx
    fld QWORD PTR [esp]
    add esp, 12
    ret
Сначала вызывается foo1. Пытаемся получить ее результат... во дела, да? Положили-то мы значение в стек FPU, а достаем откуда? Из пары EAX:EDX. Почему так произошло? Потому что компилятор ориентируется на типизацию, когда генерирует код. Объект 8 байт можно и нужно передать через регистры EAX:EDX, а вот double лучше передавать через FPU. Мы обманули его и получили некорректную программу. Если заменить вот этот блок
Assembler
1
2
3
    mov DWORD PTR [esp], eax
    mov DWORD PTR [esp+4], edx
    fld QWORD PTR [esp]
На
Assembler
1
2
    fstp  QWORD PTR [esp]
    fld  QWORD PTR [esp]
То все придет в норму. И числа показываться будут одинаковые.
В твоем коде картина та же.
 
Текущее время: 04:51. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru