|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav, уже говорил и скажу еще раз, для тех кто в танке - юзай fold expression моя идея представлена ниже (это только набросок, но он вполне пригоден для ее понимания и даже компилируется, проверил) дальше доводить ее до ума придется тебе самому Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105.
если ты попробуешь передать в my_printf значение неизвестного type_processor типа, то на этапе компиляции уже получишь ор. Добавив специализаций type_processor можно покрыть все стандартные типы, которые должна жрать и преобразовывать к строке my_printf, таким образом, можно расширять набор ее типов по мере необходимости. Все что не входит в этот круг - идет лесом на этапе компиляции. Сможешь сделать static_assert проверку куска форматной строки на соответствие типу type_process - будешь молодец! Одна из больших проблем (опять же, как я говорил ранее) - нерегулярность форматной строки. В моем примере все типы четко фиксируемые двумя символами %[symbol]. Как проанализировать форматную строку в компайл тайме с нерегулярной структурой я хз, но кто-то говорил выше, что это - ерунда, ну, тогда я уверен, все у вас получится Вторая большая проблема - размер буфера под выходные данные. В своем примере его задал статически, но если получится все что написано выше, то размер можно посчитать таким же макаром через fold expression. Это можно сделать в тех же type_expression специализациях, добавив в них функции calculate_size или переопределив оператор (). Сначала прогоняешь по форматной строке и типам с целью определения размера необходимого буфера, выделяешь его, потом выполняешь окончательную обработку с записью полученного результата, как показано у меня в примере. может это https://habr.com/ru/post/428846/ еще поможет или натолкнет на какие-то мысли по анализу форматной строки в compile time PS. я не стал заморачиваться с std::decay_t, но тебе придется ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 13:26 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum, Код: plaintext 1.
Ну и где здесь fold-expression над типом? ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 13:45 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav Господа, нам осталось решить одну проблему: как в одном вызове совместить и статическую проверку данных и динамическую печать данных? Желательно найти выход без макросов. Неужели выхода нет?! :-((( Вот псевдокод, он не компилируется: Чтобы применить static_assert к выражению, все его составляющие должны быть известны на этапе компиляции. В частности это означает что строка формата не может быть аргументом функции, а должна быть передана как аргумент шаблона. Поэтому без макроса нельзя обойтись если вы хотите чтобы для юзера все выглядело как обычная функция. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 13:57 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky Ну и где здесь fold-expression над типом? ))) в type_processor'e специализация выбирается на основе типа, нет специализации - нет компиляции. ясен пень, что fold expression не сделает цепочку типов, это и не подразумевалось, странно, что приходится это объяснять, в особенности после того, как я привел аж два примера иллюстрирующих мое высказывание ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 14:16 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum ясен пень, что fold expression не сделает цепочку типов, это и не подразумевалось, странно, что приходится это объяснять, в особенности после того, как я привел аж два примера иллюстрирующих мое высказывание Начнем с того что fold было приведено как замена рекурсивной обработки списка типов в компайл-тайм. При этом все примеры работают не с типами и не в компайл-тайм. Если мы вместо типов работаем со значениями, то все что тут делает fold можно сделать и обычным циклом ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 14:32 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum petrav, уже говорил и скажу еще раз, для тех кто в танке - юзай fold expression моя идея представлена ниже (это только набросок, но он вполне пригоден для ее понимания и даже компилируется, проверил) дальше доводить ее до ума придется тебе самому Спасибо за код. :) На уровне концепции я его понял. Но он не будет работать в compile time. И Вы делаете немного не то что Вас просят. :) Строку формата в стиле "%21.567f" я уже разбирал compile-time выше в этой ветке. Только что я написал рекурсивный обход по типам тоже compile time. Осталось совместить. И погуглить как строку формата сделать аргументом шаблона. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 16:40 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum в type_processor'e специализация выбирается на основе типа, нет специализации - нет компиляции. Кстати! В Вашем коде есть очень большой изъян. Нет специализации, но есть приведение типов! Именно поэтому у вас получилось написать специализацию для const char *, хотя в Вашем примере аргумент "some string" -- это не const char * ! Это массив. Вот Ваш тестовый код: Код: plaintext 1.
Т.е. Вы с таким подходом можете написать специализацию для double, но забыть специализацию для char. И Ваш код, при передаче char, будет компилироваться, но не будет проверять соответствие типов аргументов и строки формата. Даже в run time! Мне так кажется. Т.е. правильно говорит Anatoly Moskovsky, Вы работаете не с типами. Вы работаете со значениями. Вот мне пришлось помучится что бы написать специализацию для аргумента (не формата) в стиле "some string". Потому что эти рекурсивные шаблоны чётко руководствуются типом, а не значением. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 19:17 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav Вот мне пришлось помучится что бы написать специализацию для аргумента (не формата) в стиле "some string" Cerebrum PS. я не стал заморачиваться с std::decay_t, но тебе придется откуда вы только беретесь такие со своим Московским... Модератор: Вложение удалено. Модератор: Вложение удалено. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 19:34 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum petrav Вот мне пришлось помучится что бы написать специализацию для аргумента (не формата) в стиле "some string" Cerebrum PS. я не стал заморачиваться с std::decay_t, но тебе придется откуда вы только беретесь такие со своим Московским... Так я и не утверждаю, что разбираюсь в С++17. Но не очень понятно, что будет в Вашем примере, если мы определим перегрузку (явную специализацию шаблона) только для double, подставим %12f в виде формата, подставим char в runtime как аргумент, а потом всё это передадим в snprintf(). Передача в snprintf() это требование. И причём тут std::decay... ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 20:23 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum petrav Вот мне пришлось помучится что бы написать специализацию для аргумента (не формата) в стиле "some string" Cerebrum PS. я не стал заморачиваться с std::decay_t, но тебе придется откуда вы только беретесь такие со своим Московским... Мне кажется, Вы задействовали механизм преобразования типов аргументов. А по ТЗ нужно однозначно и чётко проверить соответствие типов аргументов и строки формата. В compile time. Ну или хотя бы в run time, но однозначно. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 20:52 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav И Вы делаете немного не то что Вас просят. :) Ну так всегда бывает, когда узнал новую фичу, и теперь суешь ее везде без разбору ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 20:53 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav И причём тут std::decay... std::decay автоматически выведет тип указателя из типа строкового литерала (без явного указания типов) ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 20:55 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky petrav И причём тут std::decay... std::decay автоматически выведет тип указателя из типа строкового литерала (без явного указания типов) Да, я это понял... со второго раза, правда. Но лучше поздно, чем... Я думаю "std::decay" тут ненужен. Он сносит дополнительную информацию с типов, а это ни к чему, мы всё проверим compile time. Я тут проще и надёжнее вещь спрограммировал. И Вы знаете, все "static_assert" работают, достаточно инвертировать условие -- и тут же код перестаёт собираться. Если аргумент "12.8" переделать на "12.8F", то код тоже перестаёт собираться. Т.е. корректность максимальная. Вот тестовый код: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
А вот код обхода типов compile time, основанный на Вашем примере. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.05.2020, 19:33 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav Если аргумент "12.8" переделать на "12.8F", то код тоже перестаёт собираться. Т.е. корректность максимальная. Код: plaintext
... |
|||
:
Нравится:
Не нравится:
|
|||
03.05.2020, 21:53 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
a guest petrav Если аргумент "12.8" переделать на "12.8F", то код тоже перестаёт собираться. Т.е. корректность максимальная. Код: plaintext
В каком смысле ОК? В плане стандарта C++, да ОК. В плане однозначной проверки типов -- супер ОК. Не написана специализация для "float" и выключено приведение типов. Компиляция ломается. Это Супер ОК. Только что написал специализацию для "float" -- тут же начало компилироваться. Или Вы про различие "%f", "%lf" и "%Lf" ? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.05.2020, 22:29 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav a guest пропущено... В каком смысле «максимальная корректность», если Код: plaintext
В каком смысле ОК? Просто странно читать про «максимальную корректность» чекера аргументов, который должен разрешать всё то, что допустимо для обычного printf, а он отказывается компилировать. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.05.2020, 23:45 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
a guest petrav пропущено... В каком смысле ОК? Под «максимальной корректностью» имелась в виду возможность однозначно в compile time детектировать тип аргумента. И запретить приведение типов. Т.е. под корректностью имелась возможность чётко увидеть тип. И никаких "std::decay". a guest Просто странно читать про «максимальную корректность» чекера аргументов, который должен разрешать всё то, что допустимо для обычного printf, а он отказывается компилировать. Нет… Чекер, наоборот должен запрещать всякие бессмысленные изыски. Зачем "%d", если есть "%i" ? На сайте cppreference написано, что "%f" и "%lf" эквивалентны. А `%Lf` -- это "long double", которая с 2005-го года не 80-т бит, а соответствует "double". Кстати, зачем нам аргументы типа "float" ? Да по-запрещать всё к чертям. Я такие бардаки годами разбираю. И везде какие-то глюки и косяки. Нам нужно сузить формат, а потом расширить его на печать, например, углов. С авто. преобразованием радиан в углы. И это тоже уменьшит количество косяков. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 00:38 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
А может, всё-таки проще компилятор сменить? Что вы так к убогой студии привязались?.. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 00:53 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov А может, всё-таки проще компилятор сменить? Что вы так к убогой студии привязались?.. Я так понял что помимо printf надо будет реализовать нестандартные форматы, и смена компилятора тут не поможет. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 01:02 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Да все претензии по форматной печати можно адресовать к конкретной библиотеке. Вот ее и ругайте. Компиллятор-то тут причем? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 10:12 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov А может, всё-таки проще компилятор сменить? Что вы так к убогой студии привязались?.. Студия прекрасна. Я почитал документацию, да хорошая штука: Код: plaintext 1. 2. 3. 4. 5. 6.
В Студии есть аналогичный атрибут: _Printf_format_string_. И там ещё куча атрибутов, другое дело что активация этого анализатора кода у меня сборку проекта замедляет в шесть раз. И начинают лезть предупреждения на сторонние библиотеки. Не знаю что делать с этим. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 11:22 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky Dimitry Sibiryakov А может, всё-таки проще компилятор сменить? Что вы так к убогой студии привязались?.. Я так понял что помимо printf надо будет реализовать нестандартные форматы, и смена компилятора тут не поможет. Да... вот только... Код: plaintext 1. 2. 3. 4. 5.
Собственная compile time проверка формата с преобразованием значений в run time имела бы смысл в таких случаях: Код: plaintext 1. 2. 3. 4.
Смутные сомнения об overengineering меня, конечно, терзали с самого начала... ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 12:29 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav Смутные сомнения об overengineering меня, конечно, терзали с самого начала... на мой взгляд для type rich кода следует использовать operator "" с собственными суффиксами для типов и перегрузку operator <<, а не измываться над printf, который уже много раз предавали анафеме ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 12:49 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum petrav Смутные сомнения об overengineering меня, конечно, терзали с самого начала... на мой взгляд для type rich кода следует использовать operator "" с собственными суффиксами для типов и перегрузку operator <<, а не измываться над printf, который уже много раз предавали анафеме ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 12:50 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum petrav Смутные сомнения об overengineering меня, конечно, терзали с самого начала... на мой взгляд для type rich кода следует использовать operator "" с собственными суффиксами для типов и перегрузку operator <<, а не измываться над printf, который уже много раз предавали анафеме Вы имеете в виду операторы в стиле "123.4_rad" ? Да, штука хорошая, но это уже про написание литералов, а не про печать данных. Вообще, анафеме нужно предать библиотеку <iostream>. Совершено непонятно о чём думали люди которые это проектировали. Ведь были же все языковые инструменты, что бы разработать type safe форматирование строк в стиле "printf()" -- как это сделали в "QString" и "boost::format", например. Впрочем, C++ это язык для создания велосипедов и костылей. Может они неосознанно так проектировали <iostream>, что бы пользователей спровоцировать к творчеству через шок. Кстати, Страуструп, собственно, и писал, что C++ проектируется так, что бы пользователи могли расширять язык своими типами. Видимо многоуважаемый Бьёрн передал эту мысль другим проектантам и они накосячили не осознанно. А может и осознанно... ... |
|||
:
Нравится:
Не нравится:
|
|||
04.05.2020, 16:48 |
|
|
start [/forum/topic.php?fid=57&msg=39953610&tid=2017436]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
others: | 11ms |
total: | 150ms |
0 / 0 |