Вы мне предлагали фантазировать на тему constexpr, а сами не хотите фантазировать, тем более что ваш код не компилируется уже по причине того что нельзя char * p = "123456789";. Честно, я уже потерял нить того, что вы мне доказываете. Спор ради спора? У меня и так есть чем занять свое время.
Здравствуйте, Videoman, Вы писали:
V>То-есть вы допускаете в STL существование своих функции вычисления значений и отказываете STL в возможности написания своих функций обхода?
Я не сказу за всю современную библиотеку С++20 с std::ranges, но в целом — да. Однако, обычно набора функций std:: хватает для решения задач.
V>На практике у меня функция собственно и инкапсулирует алгоритм прохода по итераторам, он не тривиальный и такого в STL быть не может.
Это смотря что понимать под "не тривиальный". Если у вас цикл или набор циклов по последовательности, то скорее всего можно обойтись функциями из std::
А вот если у вас такой алгоритм, где необходимы обратные смещения по последовательности и число обратных смещений не фиксировано, то тогда на может быть нет смысла использовать STL
Здравствуйте, Videoman, Вы писали:
V>Вы мне предлагали фантазировать на тему constexpr, а сами не хотите фантазировать
Мне не нужно фантазировать, это вы показали, к какому коду в итоге пришли:
template<typename It, std::enable_if_t<is_const_iterator_of_v<It, char>, int> = 0>
constexpr It CalcSomething(It str, It last) noexcept;
template<typename It, std::enable_if_t<is_const_iterator_of_v<It, char16_t>
|| (is_const_iterator_of_v<It, wchar_t> && sizeof(wchar_t) == sizeof(char16_t)), int> = 0>
constexpr It CalcSomething(It str, It last) noexcept;
template<typename It, std::enable_if_t<is_const_iterator_of_v<It, char32_t>
|| (is_const_iterator_of_v<It, wchar_t> && sizeof(wchar_t) == sizeof(char32_t)), int> = 0>
constexpr It CalcSomething(It str, It last) noexcept;
Здесь один тип итератора. И если в итоге вы сделали вариант с двумя типами итераторов, значит мой пример был приведен не зря.
V>При этом ранее вы заостряли внимание на том, что тем более что ваш код не компилируется уже по причине того что нельзя char * p = "123456789";.
Это не ошибка, а предупреждение. Для иллюстрационного примера вполне простительно.
Здравствуйте, so5team, Вы писали:
S>Здесь один тип итератора. И если в итоге вы сделали вариант с двумя типами итераторов, значит мой пример был приведен не зря.
У меня в коде именно что один тип итератора . Ваш вариант не скомпилируется, просто у меня нет таких экзотических случаев нигде в коде. Если будет необходимо, я могу разделить типы, это ни на что не повлияет. Еще раз, я-то как раз не оправдываю сложность и объем кода которые в итоге получились, но еще раз, посмотрите повнимательнее на название темы. Весь мой вопрос заключался в одном: неужели для того что бы сделать полностью эквивалентный изначальному код на итераторах нужно так извращаться? Ответ: да!
Здравствуйте, Videoman, Вы писали:
V>Весь мой вопрос заключался в одном: неужели для того что бы сделать полностью эквивалентный изначальному код на итераторах нужно так извращаться? Ответ: да!
При этом не стоит упускать из виду, что наиболее удачный рефаторинг — это не обязательно полностью эквивалентный код
Здравствуйте, Videoman, Вы писали:
S>>Здесь один тип итератора. И если в итоге вы сделали вариант с двумя типами итераторов, значит мой пример был приведен не зря.
V>У меня в коде именно что один тип итератора . Ваш вариант не скомпилируется, просто у меня нет таких экзотических случаев нигде в коде.
В C++ном range-for изначально тоже предполагалось, что у begin/end будет одинаковый тип. Но затем в C++17 пришлось вносить изменения.
V>Если будет необходимо, я могу разделить типы, это ни на что не повлияет.
Разве что на объем и сложность кода, т.к. вам придется вписывать дополнительные проверки.
V>Весь мой вопрос заключался в одном: неужели для того что бы сделать полностью эквивалентный изначальному код на итераторах нужно так извращаться? Ответ: да!
Есть замечательное изречение: "Вы дали ему то, что он просил. А я дал ему то, что ему было нужно". Вы явно ждали лишь того, о чем просили.
Если у вас появилось впечатление, что я пытаюсь в этом разговоре как-то унизить вас или продемонстрировать какое-то превосходство, то уверяю, это не так.
Дело в том, что я так же разрабатываю библиотеки, которые затем разные люди используют в разных условиях и для разных задач. Но исходя из своего опыта я не смог понять под какие сценарии вы затачиваете свой условный calc_something. В частности, от меня ускользают сценарии, в которых пользователь вашей библиотеки будет иметь возможность делать собственные перегрузки ваших функций и почему это может помешать шаблонным функциям в ваших пространствах имен. Отсюда и вопросы. Жаль, что тема использования ADL не получила своего развития. Я так и не понял, как взаимосвязаны разные реализации calc_something в разных пространствах имен с ADL.
Здравствуйте, so5team, Вы писали:
S>В C++ном range-for изначально тоже предполагалось, что у begin/end будет одинаковый тип. Но затем в C++17 пришлось вносить изменения.
Да, про это я в курсе. Все готовятся к range-ам. Будем решать проблемы по мере их поступления. Пока мы плотно сидим старом С++17. На самом деле не известно насколько все это будет удобно и сколько кода придется писать и как быстро все это будет работать, когда народ массово кинется на 20 стандарт. Посмотрим.
S>Если у вас появилось впечатление, что я пытаюсь в этом разговоре как-то унизить вас или продемонстрировать какое-то превосходство, то уверяю, это не так.
S>Дело в том, что я так же разрабатываю библиотеки, которые затем разные люди используют в разных условиях и для разных задач. Но исходя из своего опыта я не смог понять под какие сценарии вы затачиваете свой условный calc_something. В частности, от меня ускользают сценарии, в которых пользователь вашей библиотеки будет иметь возможность делать собственные перегрузки ваших функций и почему это может помешать шаблонным функциям в ваших пространствах имен. Отсюда и вопросы. Жаль, что тема использования ADL не получила своего развития. Я так и не понял, как взаимосвязаны разные реализации calc_something в разных пространствах имен с ADL.
На самом деле я действительно получил исчерпывающее объяснение на изначальный вопрос и дальнейшее обсуждение выльется в то, что мне просто придется выкладывать кучу кода из библиотеки. Дальше мы начнем обсуждать дальнейшие нюансы и т.д. и т.п. С++ можно обсуждать бесконечно, но к сожалению сейчас просто нет на это времени.
Здравствуйте, vopl, Вы писали:
V>Здравствуйте, vopl, Вы писали:
V>>Здравствуйте, Videoman, Вы писали:
V>>>- преобразовать тип итераторов — я не могу
V>для компайл тайм это тоже работает, https://gcc.godbolt.org/z/8nnWfE
Идею я понял, но для меня это слишком креативно . И к сожалению на С++17 не работает, reinterpret_cast там никак.
Здравствуйте, Videoman, Вы писали:
V> к сожалению на С++17 не работает
работает https://gcc.godbolt.org/z/d8so4n
V> reinterpret_cast там никак.
это мелочи, я его туда вкорячил потому что было лень думать. Вместо него можно другие средства запользовать. Например, можно вообще ссылку не предоставлять из operator*, а сразу значение (если тебя это устроит, мне со стороны не видно) — тогда не нужно будет спускаться на уровень указателей, следовательно, никаких ХХХ_cast для указателей вообще. Это лишь пример, не более.
Здравствуйте, vopl, Вы писали:
V>это мелочи, я его туда вкорячил потому что было лень думать. Вместо него можно другие средства запользовать. Например, можно вообще ссылку не предоставлять из operator*, а сразу значение (если тебя это устроит, мне со стороны не видно) — тогда не нужно будет спускаться на уровень указателей, следовательно, никаких ХХХ_cast для указателей вообще. Это лишь пример, не более.
Идея с адаптером супер. Буду иметь в виду если прижмет где-то. В продакшене я боюсь такое использовать пока
А вот интересный у меня вопрос, так как я с концептами в живую еще не сталкивался: вот это вот:
template<const_iterable_of_type<wchar_t> It>
constexpr int CalcSomething(It beg, It end)
Будет разрешаться когда оба итератора строго одного типа или, в отличие от варианта на С++, будет позволять любые типы подходящие под concept ? Сдается мне что будет выведен какой-то один тип и придется также дублировать:
V>А вот интересный у меня вопрос, так как я с концептами в живую еще не сталкивался: вот это вот: V>
V>template<const_iterable_of_type<wchar_t> It>
V>constexpr int CalcSomething(It beg, It end)
V>
V>Будет разрешаться когда оба итератора строго одного типа или, в отличие от варианта на С++, будет позволять любые типы подходящие под concept ?
В смысле, чтобы работал следующий вызов?
Тогда если в теле функции CalcSomething будет написано It a;, то какой тип из двух должна получить эта переменная a?
V>Сдается мне что будет выведен какой-то один тип
Да. Конструкция
template<Concept T>
auto foo(T param) …
эквивалентна
template<typename T>
requires Concept<T>
auto foo(T param) …
Из этого должно быть понятно как ограничения работают в случае многих параметров.
V>Что говорят концепты? Это можно будет на них как-то упростить?
Если тебе не нужно что-то дополнительное от типа, то можно просто не использовать полную запись: выкинуть template и использовать concept auto для аргументов. Работает так же как и в остальных местах: каждый auto выводится независимо.