|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
По мотивам статьи вот здесь . Если коротко, человек написал вариативный шаблон функции, которая есть быть обёрткой вокруг `std::printf()`. Вариативные аргументы шаблона передаются «as is» в `printf()`. Если отбросить нюансы семантики копирования и т.п. Ну... Вопрос № 1: насколько это соответствует стандарту С++? Они бинарно совместимы? Идём далее. Пример из его статьи: Код: plaintext 1. 2. 3. 4. 5. 6.
Вопрос № 2: в какой последовательности согласно стандарту вызывается функция `Argument()` для вариативных шаблонных параметров? Это определено стандартом или нет? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 16:19 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav Вопрос № 1: насколько это соответствует стандарту С++? Они бинарно совместимы? Соответствует. Бинарная совместимость не требуется. Это два ортогональных механизма. Распаковка пакета параметров оператором "..." - это просто синтаксический сахар и все работает также как если бы вы аргументы передавали в printf явным перечислением. petrav Вопрос № 2: в какой последовательности согласно стандарту вызывается функция `Argument()` для вариативных шаблонных параметров? Это определено стандартом или нет? Порядок вычисления аргументов неопределен (IIRC, кроме некоторых исключений для перегруженных операторов в свежих версиях стандарта) независимо от того как подставляются аргументы, из вариативного пакета параметров или явным перечислением. А какая разница? Это не влияет на рабочесть примера. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 19:03 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky petrav Вопрос № 1: насколько это соответствует стандарту С++? Они бинарно совместимы? Соответствует. Бинарная совместимость не требуется. Это два ортогональных механизма. Распаковка пакета параметров оператором "..." - это просто синтаксический сахар и все работает также как если бы вы аргументы передавали в printf явным перечислением. Окей, я Вас понял. Anatoly Moskovsky petrav Вопрос № 2: в какой последовательности согласно стандарту вызывается функция `Argument()` для вариативных шаблонных параметров? Это определено стандартом или нет? Порядок вычисления аргументов неопределен (IIRC, кроме некоторых исключений для перегруженных операторов в свежих версиях стандарта) независимо от того как подставляются аргументы, из вариативного пакета параметров или явным перечислением. А какая разница? Это не влияет на рабочесть примера. А разница **большая**. Я хочу разработать обёртку вокруг `printf()` которая хотя бы на этапе исполнения проверяла строку формата и типы переданных аргументов. Лучше на этапе компиляции. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 19:19 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky, Для этого мне нужно что бы функция `Argument()` вызывалась последовательно в вышеприведённом примере. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 19:21 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav А разница **большая**. Я хочу разработать обёртку вокруг `printf()` которая хотя бы на этапе исполнения проверяла строку формата и типы переданных аргументов. Лучше на этапе компиляции. Для этого мне нужно что бы функция `Argument()` вызывалась последовательно в вышеприведённом примере. Зачем для этого последовательно вызывать какую-то функцию для каждого аргумента? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 20:21 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky petrav А разница **большая**. Я хочу разработать обёртку вокруг `printf()` которая хотя бы на этапе исполнения проверяла строку формата и типы переданных аргументов. Лучше на этапе компиляции. Для этого мне нужно что бы функция `Argument()` вызывалась последовательно в вышеприведённом примере. Зачем для этого последовательно вызывать какую-то функцию для каждого аргумента? Ну идея такая. Мы перегружаем функцию `Argument()` для каждого стандартного типа, но одновременно передаём в `Argument()` парсер формата, который в своём состоянии хранит текущий указатель на символ строки формата и мы можем проверить соответствие типа в формате и того, что передано в вариативных шаблонных аргументах. Для не стандартных типов срабатывает шаблонная перегрузка и там `static_assert`. Но лучше конечно compile time. PS: Да, придётся написать свой парсер формата `printf()`, но я думаю это макс на пару дней работы без написания тестов. Т.е. на коленке. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 20:34 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky, Если у Вас есть какое-то лучшее решение в стиле: Код: plaintext 1. 2. 3. 4.
Так Вы сообщите, плиз. Я не особо изучал С++17. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 21:09 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav, Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Это в рантайме. В компайл-тайме тоже наверно как-то можно, лень думать. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 22:02 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav Но лучше конечно compile time. PS: Да, придётся написать свой парсер формата `printf()`, но я думаю это макс на пару дней работы без написания тестов. Т.е. на коленке. Код: plaintext
... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 22:07 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky Это в рантайме. Это замечательно, но... Код: plaintext 1. 2. 3. 4. 5. 6. 7.
Я примерно понимаю о чём вы говорите. Наш рекурсивый шаблон зависит от типа первого параметра, он наследуется от самого себя, но предок зависит от типа второго параметра и т.д. Да? Но как это сделать?! Как пронавигировать по Args? Пожалуйста. :) Anatoly Moskovsky В компайл-тайме тоже наверно как-то можно, лень думать. Ну мы тут ни куда же не торопимся. Лень, так лень. Подумаем через неделю. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 22:19 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav, Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.04.2020, 23:48 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav, рекурсивные шаблоны - зло, особенно для компилятора, их место уже занял fold expression в качестве примера https://www.qt.io/blog/efficient-qstring-concatenation-with-c17-fold-expressions ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 09:38 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum рекурсивные шаблоны - зло, особенно для компилятора, их место уже занял fold expression Вообще-то fold expr не применим к типам. Так что пока не добавят в стандарт итерацию по списку типов придется использовать рекурсивные шаблоны. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 13:38 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
В принципе если еще дальше перейти в рантайм, то можно избавиться от рекурсивных шаблонов. Код: 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.
PS. Правда fold expressions и тут не нужны )) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 14:00 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Какой смысл затаскивать в обсуждение Си? Это - контр-продуктивно вообще. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 14:00 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky Вообще-то fold expr не применим к типам. прекрасно пременим, если их состав известен (при необходимости может быть расширен за счет добавления нужных специализаций). я привел пример, в котором производится конкатенация строк, но кто мешает расширить состав обрабатываемых типов, раз уж тут пытаются сэмулировать работу printf, набор типов которой описывается форматной строкой, где каждому типу сопоставлена лексема? [spoiler] Если примера недостаточно, то вот еще один, ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 15:18 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky В принципе если еще дальше перейти в рантайм, то можно избавиться от рекурсивных шаблонов. Ого... А говорили думать лень. Я правда просил только пример рекурсивного шаблона, но Ваш развёрнутый код очень познавателен. Спасибо! Но уходить желательно в compile time. Если взять за основу Ваш первый прототип... То имхо, std::vector не нужен. Проходить по строке формата нужно одновременно с навигацией по типам. Оказались в перегрузке для double -- начали искать в строке формата `%f`. Тогда состояние парсера будет описываться одним указателем на char. И, наверное, можно будет сделать compile time. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 15:21 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
mayton Какой смысл затаскивать в обсуждение Си? Это - контр-продуктивно вообще. Может printf() кривой, но он очень удобен и производителен. Тут у меня код программный... ему уже лет 30-ть. Тут вообще хардкор нереал. :) Но он работает... ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 15:26 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
petrav, на мой взгляд пройтись по типам в variadic pack'e - вообще не проблема, проблема будет в том, чтобы в компайл тайме обеспечить парсинг фоматной строки, если каждому типу в ней не будет отведено строго обозначенное кол-во символов, чего в реальном printf не было никогда. Например, тип може быть задан с префиксом указывающем точность округления - %0.5f, и тогда это уже не будет %f для compile-time парсера. Если же у вас форматная строка всегда четко вида %[type symbol], то можно попробовать в complle time ее разобрать на составляющие (я не пробовал, но если форматная строка - лексема, то думаю, что это реально). А типы сопоставить - это фигня. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 15:29 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum petrav, на мой взгляд пройтись по типам в variadic pack'e - вообще не проблема, проблема будет в том, чтобы в компайл тайме обеспечить парсинг фоматной строки, если каждому типу в ней не будет отведено строго обозначенное кол-во символов, чего в реальном printf не было никогда. Например, тип може быть задан с префиксом указывающем точность округления - %0.5f, и тогда это уже не будет %f для compile-time парсера. Если же у вас форматная строка всегда четко вида %[type symbol], то можно попробовать в complle time ее разобрать на составляющие (я не пробовал, но если форматная строка - лексема, то думаю, что это реально). А типы сопоставить - это фигня. Нет проблем написать парсер и %f и %0.5f и вообще всех вариантов. Это простой формат, это ж не регулярные выражения. По крайней мере я так думаю. За ссылки спасибо, прочитаю. Вот Вы бы написали бы свой прототип? Но не стоит задачи написать свою библиотеку ввода вывода. Нужно создать обёртку вокруг printf(). ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 15:37 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
mayton Какой смысл затаскивать в обсуждение Си? Это - контр-продуктивно вообще. Ещё меня привлекает идея расширить стандартный формат: Код: plaintext 1.
Конечно, перед передачей в оригинальный printf() нужно и строку формата подкорректировать до стандартной. Но это уже в run time, конечно. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 15:59 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Я думаю что тебе нужна Scala и ее implicit conversions. Ты - постигнешь дзен и твоя душа придёт в состояние гармонии. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 16:51 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Очередной этап изысканий. Cerebrum Например, тип може быть задан с префиксом указывающем точность округления - %0.5f, и тогда это уже не будет %f для 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 16:56 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Cerebrum прекрасно пременим, если их состав известен (при необходимости может быть расширен за счет добавления нужных специализаций). Не применим. Потому что в С++ нет бинарных операторов применимых к типам. А fold expression это применение операторов к списку сущностей. И поскольку есть только операторы применимые к значениям, то fold expression возможен только для пакета параметров, но не пакета типов этих параметров. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.04.2020, 19:05 |
|
Вариативные шаблоны C++ и вариативные функции Си
|
|||
---|---|---|---|
#18+
Господа, нам осталось решить одну проблему: как в одном вызове совместить и статическую проверку данных и динамическую печать данных? Желательно найти выход без макросов. Неужели выхода нет?! :-((( Вот псевдокод, он не компилируется: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
А вот жуткое решение на вариативных макросах: Код: 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.
Заранее спасибо! ... |
|||
:
Нравится:
Не нравится:
|
|||
01.05.2020, 09:17 |
|
|
start [/forum/topic.php?fid=57&msg=39951658&tid=2017436]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
39ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 266ms |
total: | 415ms |
0 / 0 |