Все отлично работает, был простой код. Не совсем гибко, а давайте еще обобщим и добавим что бы работало с любыми итераторами.
Проблема первая, как перегрузить итераторы только для перечисленных типов? Ну я ничего лучше не придумал чем (может кто подскажет как правильно):
template<class Type>
struct decay_with_const
{
using NonRefType = std::remove_reference_t<Type>;
using type = std::conditional_t<std::is_array_v<NonRefType>,
std::add_pointer_t<std::remove_extent_t<NonRefType>>,
std::conditional_t<std::is_function_v<NonRefType>,
std::add_pointer_t<NonRefType>,
std::remove_volatile_t<NonRefType>>>;
};
template<class _Ty>
using decay_with_const_t = typename decay_with_const<_Ty>::type;
стандартный decay не подходит, так как убирает const.
И начаинается...
— преобразовать тип итераторов — я не могу
— перебразовать в указатели — я не могу, т.к. &*begin, &*end — нельзя разыменовывать если они указывают за конец данных (например у string_view) и т.д.
Вопрос:
Где как можно выйти в такой ситуации. Вроде задача элементарная, но времени отняла уже прилично. Так и чувствую себя как ослик бегущий за морковкой, ногу вытащишь, хвост увязнет и т.д.
Здравствуйте, Videoman, Вы писали:
V>Вопрос: V>Где как можно выйти в такой ситуации. Вроде задача элементарная, но времени отняла уже прилично. Так и чувствую себя как ослик бегущий за морковкой, ногу вытащишь, хвост увязнет и т.д.
Здравствуйте, Videoman, Вы писали:
V>За что я "люблю" эту концепцию STL так это за то, что наступаешь на грабли в самых казалось бы простых вещах! V>Захотел написать обобщенный код, было:
V>
V>Все отлично работает, был простой код. Не совсем гибко, а давайте еще обобщим и добавим что бы работало с любыми итераторами. V>Проблема первая, как перегрузить итераторы только для перечисленных типов? Ну я ничего лучше не придумал чем (может кто подскажет как правильно):
попробуй через перегрузку (не проверял):
constexpr uint_t CalcSomething(I beg, I end, type_identity<char>) // ...
constexpr uint_t CalcSomething(I beg, I end, type_identity<char16_t>) // ...
constexpr uint_t CalcSomething(I beg, I end, type_identity<char32_t>) // ...
constexpr uint_t CalcSomething(I beg, I end) {
return CalcSomething(beg, end, type_identity<typename std::decay<decltype(*beg)>::type>{})
}
V>стандартный decay не подходит, так как убирает const.
Здравствуйте, Videoman, Вы писали:
V>И начаинается... V>- преобразовать тип итераторов — я не могу V>- перебразовать в указатели — я не могу, т.к. &*begin, &*end — нельзя разыменовывать если они указывают за конец данных (например у string_view) и т.д.
Ну да, получается не можешь. В общем случае итераторы разных типов взаимно не преобразуемы — так же, как и их контейнеры.
V>Вопрос: V>Где как можно выйти в такой ситуации. Вроде задача элементарная, но времени отняла уже прилично. Так и чувствую себя как ослик бегущий за морковкой, ногу вытащишь, хвост увязнет и т.д.
Мне кажется, основная проблема в том, что ты пытаешься cделать обобщение в привязке к типу, тогда как здесь было бы уместнее делать обобщение в привязке к размеру, если я правильно понимаю задачу. Тогда версия для wchar_t просто отпала бы за недадобностью:
Здравствуйте, Voivoid, Вы писали:
V>Ну, например, если ничего не упустил, как-то так ( https://ideone.com/m8igyh ): V>[ccode] V>template <typename Iter> V>using iter_val_t = typename std::iterator_traits< Iter >::value_type;
V>template <typename Iter, typename T> V>constexpr bool is_T_iter_v = std::is_same< iter_val_t< Iter >, T >::value;
V>template <typename Iter> V>constexpr bool is_wchar_iter_v = std::is_same< iter_val_t< Iter >, wchar_t >::value;
Ну не совсем так. Я хочу именно обобщение, т.е. должны приниматься и итераторы и голые указатели в этом и проблема. Но идею я понял, спасибо, попробую.
Здравствуйте, night beast, Вы писали:
NB>попробуй через перегрузку (не проверял):
NB>[ccode] NB>constexpr uint_t CalcSomething(I beg, I end, type_identity<char>) // ... NB>constexpr uint_t CalcSomething(I beg, I end, type_identity<char16_t>) // ... NB>constexpr uint_t CalcSomething(I beg, I end, type_identity<char32_t>) // ...
Через перегрузку этих трех методов будет работать. Проблема в том что wchar_t это не алиас, а отдельный тип и он не будет кастится, или я не понял идею.
V>>стандартный decay не подходит, так как убирает const.
NB>это же хорошо
Итератор имеет семантику указателя и я тогда не смогу передавать не константные итераторы в функцию требующую константные.
Здравствуйте, rg45, Вы писали:
R>Мне кажется, основная проблема в том, что ты пытаешься cделать обобщение в привязке к типу, тогда как здесь было бы уместнее делать обобщение в привязке к размеру, если я правильно понимаю задачу. Тогда версия для wchar_t просто отпала бы за недадобностью:
R>
У меня закралось сомнение что я не стой стороны подхожу, но я не понял твоей идеи. т.е. будет срабатывать для всех типов имеющих размер 1,2,4. Если это так, то это совсем не то что мен нужно. Мне нужно только для char, char16_t, char32_t, wchar_t (для совместимости со старым кодом)
зачем разные функции пытаться сводить в одну ?
это напоминает по моему маерса(если не ошибаюсь) который на каком то с++ конфе делал доклад
про универсальную memcpy функцию
смысл которой тоже очень похож на ваши
и итог к которому он пришел после своих долгих раздумий и попыток — это невозможно сделать красиво
Здравствуйте, Videoman, Вы писали:
V>Через перегрузку этих трех методов будет работать. Проблема в том что wchar_t это не алиас, а отдельный тип и он не будет кастится, или я не понял идею.
не будет.
для него делается 4, или какая там по счету функция, в ней определяешь какую функцию из этих вызывать и прокидываешь параметром type_identity<нужный чар>, итераторы не трогая.
не зная, что конкретно этих функциях происходит сложно сказать, подойдет или нет такое решение
V>>>стандартный decay не подходит, так как убирает const.
NB>>это же хорошо
V>Итератор имеет семантику указателя и я тогда не смогу передавать не константные итераторы в функцию требующую константные.
компилятор тебе об этом сообщит.
тебя же не парит, что в том же std::copy нету енейбла по константности итератора
Здравствуйте, night beast, Вы писали:
NB>не будет. NB>для него делается 4, или какая там по счету функция, в ней определяешь какую функцию из этих вызывать и прокидываешь параметром type_identity<нужный чар>, итераторы не трогая. NB>не зная, что конкретно этих функциях происходит сложно сказать, подойдет или нет такое решение
V>>>>стандартный decay не подходит, так как убирает const.
Ну не то. Мне не нравится когда код ломается совсем уж где-то в цепочках вызовов. Хочется добиться просто что бы перегрузка внешней функции либо срабатывала, либо нет.
NB>компилятор тебе об этом сообщит. NB>тебя же не парит, что в том же std::copy нету енейбла по константности итератора
Честно — немного парит . По-моему это не правильно. Еще раз, у меня функции должны работать не только с итераторами, но и с голыми указателями и const корректность должна соблюдаться.
Здравствуйте, reversecode, Вы писали:
R>зачем разные функции пытаться сводить в одну ? R>это напоминает по моему маерса(если не ошибаюсь) который на каком то с++ конфе делал доклад R>про универсальную memcpy функцию R>смысл которой тоже очень похож на ваши R>и итог к которому он пришел после своих долгих раздумий и попыток — это невозможно сделать красиво
Согласен, я просто могу повторить код и на этом закончить но, на мой взгляд, шаблоны именно для того и нужны что бы не дублировать логику и помогать в этом разработчику. Я просто хочу удостовериться что я ничего не упустил и понять где граница.
Здравствуйте, Videoman, Вы писали:
V>За что я "люблю" эту концепцию STL так это за то, что наступаешь на грабли в самых казалось бы простых вещах! V>Захотел написать обобщенный код, было:
Здравствуйте, Videoman, Вы писали:
V>Ну не совсем так. Я хочу именно обобщение, т.е. должны приниматься и итераторы и голые указатели в этом и проблема. Но идею я понял, спасибо, попробую.
V>У меня закралось сомнение что я не стой стороны подхожу, но я не понял твоей идеи. т.е. будет срабатывать для всех типов имеющих размер 1,2,4. Если это так, то это совсем не то что мен нужно. Мне нужно только для char, char16_t, char32_t, wchar_t (для совместимости со старым кодом)
Ну тогда просто слегка допилить фильтр. Но общим остается то, что отдельная версия для wchar_t не нужна — whar_t должен автоматом подхватываться одной из трех других версий:
Здравствуйте, Videoman, Вы писали:
V>Ну не то. Мне не нравится когда код ломается совсем уж где-то в цепочках вызовов. Хочется добиться просто что бы перегрузка внешней функции либо срабатывала, либо нет.
ну, бывает и так что потом тратишь время разбираясь, почему не находит, вот же она...
Здравствуйте, rg45, Вы писали:
R>Ну тогда просто слегка допилить фильтр. Но общим остается то, что отдельная версия для wchar_t не нужна — whar_t должен автоматом подхватываться одной из трех других версий:
R>
Ну ты описываешь самое начало, то с чего все начинают. А мне понадобилось обобщить итераторы и указатели, да так, что бы перегрузка не срабатывала когда не подходит. У тебя код самая "жадная" штука, которая принимает в себя абсолюьтно все и ломается уже в дебрях. Дальше остается только догадываться что пошло не так рассматривая простыни сообщении об ошибках. Я пытаюсь избежать такого подхода. Пытаюсь эмулировать концепты на с++17. Концепты для бедных, так сказать .
V>Ну ты описываешь самое начало, то с чего все начинают. А мне понадобилось обобщить итераторы и указатели, да так, что бы перегрузка не срабатывала когда не подходит. У тебя код самая "жадная" штука, которая принимает в себя абсолюьтно все и ломается уже в дебрях. Дальше остается только догадываться что пошло не так рассматривая простыни сообщении об ошибках. Я пытаюсь избежать такого подхода. Пытаюсь эмулировать концепты на с++17. Концепты для бедных, так сказать .
Обычно хватает, когда припирает, можно уже и по тяжелову со всякими enable_if или как там
Здравствуйте, Voivoid, Вы писали:
V>Так и указатели тоже будут работать с точно таким же кодом: https://ideone.com/AvzGNO V>
V>int main()
V>{
V> const char* p = nullptr;
V> CalcSomething( p, p );
V>}
V>
V>Или о чем речь?
Да придирки... просто насколько я понял std::iterator_traits не отличает константные итераторы от не константных. Как с std::iterator_traits сделать что-бы метод принимал итераторы/указатели только не константные, иначе говоря, что бы код выше не компилировался, а вот такой компилировался?