Russian Qt Forum
Ноябрь 24, 2024, 17:14 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Итераторные пары  (Прочитано 6762 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Январь 09, 2021, 11:54 »

Добрый день

Не раз замечал что у любителей std преобладают имена из 3 букв. Но у меня-то нет
Код
C++ (Qt)
if (std::find(mUsedThresholds.begin(), mUsedThresholds.end(), tindex) != mUsedThresholds.end())
 mUsedThresholds.push_back(tindex);
 
Да еще и неправильно (контейнер может быть пустым). Дело не в том что мне, мол, "лень писать", но оно выглядит отвратно Плачущий Ф-ционала на копейку, текста на рупь.

Прошло неск лет как это обсуждали, может появились средства языка позволяющие обойтись без таких длинных соплей? (новые стандарты и все такое)

Спасибо
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Январь 09, 2021, 12:48 »

Прошло неск лет как это обсуждали, может появились средства языка позволяющие обойтись без таких длинных соплей? (новые стандарты и все такое)
Да не нужны для этого никакие новые стандарты.
Разработчики, как правило, стараются спрятать стандартные контейнеры в классах, описывающих сущности предметной области и добавить удобные методы для их использования.
Код
C++ (Qt)
class Threshols
{
public:
   bool isContains( int val ) const
   {
       return std::find( mUsedThresholds.begin(), mUsedThresholds.end(), val ) != mUsedThresholds.end();
   }
 
   void append( int val )
   {
       if( !isContains( val ) )
           mUsedThresholds.push_back( val );
   }
 
private:
   std::vector<int> mUsedThresholds;
};
 
Заодно, когда надоест постоянно бегать по вектору для поиска, это позволит незаметно для остального кода проекта это оптимизировать.


Если делать как вы привыкли и все располагать в классе MainWindow, то всегда можно добавить шаблонную функцию isContains, тогда можно будет делать так:
Код
C++ (Qt)
if( !isContains( mUsedThresholds, tindex) )
 mUsedThresholds.push_back( tindex );
 

Но зачем вам об этом заморачиваться - копипастите и все.

Не раз замечал что у любителей std преобладают имена из 3 букв. Но у меня-то нет
Ну конечно... Вы то у нас о-го-го. Судя по вашим то темам. Улыбающийся

Да еще и неправильно (контейнер может быть пустым).
Ну и что? Если контейнер пустой, то begin() == end(). Не переживайте за стандартные алгоритмы, они с этим справляются. Улыбающийся
Но вы для верности всегда можете добавлять перед find - !mUsedThresholds.empty() &&
Тогда, читающие ваш код специалисты, сразу будут понимать с чем имеют дело.
« Последнее редактирование: Январь 09, 2021, 13:05 от Old » Записан
RedDog
Частый гость
***
Offline Offline

Сообщений: 221


Просмотр профиля
« Ответ #2 : Январь 09, 2021, 18:37 »

а почему бы в данном примере std::set не заюзать?
тогда не нужно будет это длинное условие
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Январь 10, 2021, 09:37 »

а почему бы в данном примере std::set не заюзать?
тогда не нужно будет это длинное условие
Не, ну выбор контейнера определяется др соображениями, они могут быть самыми разными.

Мда, похоже что "а воз и ныне там". Нормально было бы так
Код
C++ (Qt)
if (!mUsedThresholds.contains(tindex))
 mUsedThresholds.push_back(tIndex);
Кстати "обветшавшие" Qt контейнеры все это имеют: find, contaiins, indexOf и.т.п. А добиться того же великом оказывается не так уж просто. Напр
Код
C++ (Qt)
template<class T, class Val>
bool MyContains( const T & vec, Val val )
{
 return std::find(vec.begin(), vec.end(), val) != vec.end();
}
Это запросто сработает для мапы убивая ф-ционал. На мой взгляд лучше скромное
Код
C++ (Qt)
template<class T, class Val>
bool VecContains( const std::vector<T> & vec, Val val );
Ну и дублить если еще понадобится (напр для деки). Все равно хорошего впечатления не производит. "Костыль", а хотелось бы "ис каропки"
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Январь 10, 2021, 10:00 »

Это запросто сработает для мапы убивая ф-ционал.
Вам нужно лучше изучить инструмент, который вы пытаетесь использовать.
Для мапы код не скомпилируется (поэтому убийтсва функционала не последует Улыбающийся ), итератор мапа при разименовании не дает валуе.
К тому же у мапа есть свой метод для этого.
Даже если в коде был вектор и его заменили на мап, то при первой же сборке возникнет ошибка и разработчик замент этот вызов на соответствующий метод мапа.

Код
C++ (Qt)
template<class T, class Val>
bool VecContains( const std::vector<T> & vec, Val val );
Это что, идентификаторы из 3 букв? Улыбающийся
А где же "Но у меня-то нет", или тайный любитель std? Улыбающийся
« Последнее редактирование: Январь 10, 2021, 10:17 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Январь 12, 2021, 11:44 »

Может симпатичнее оформить как namеspace и юзать так
Код
C++ (Qt)
if (std_ext::contains(mUsedThresholds, tindex)) ..
Вроде ничего, но вот как пресечь для мапы и др контейнеров имеющих свой (быстрый) find - хз. Правда и само std::find этого не делает
Записан
ksk-
Самовар
**
Offline Offline

Сообщений: 178



Просмотр профиля
« Ответ #6 : Январь 12, 2021, 12:27 »

Возможно, не до конца понял суть вопроса. Но что насчёт https://en.cppreference.com/w/cpp/ranges?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Январь 12, 2021, 13:24 »

но вот как пресечь для мапы и др контейнеров имеющих свой (быстрый) find - хз.
Что-бы было не "хз", нужно книжку почитать по c++. Улыбающийся
Но можно и дальше на форуме решения клянчить. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Январь 14, 2021, 11:54 »

Возможно, не до конца понял суть вопроса. Но что насчёт https://en.cppreference.com/w/cpp/ranges?
Да "суть" тут "под каждым кустом" Улыбающийся Просто хочется схлопнуть код что выглядит неопрятно. Неужели для этого надо иметь последний стандарт, освоить новую концепцию и.т.п? Ну как-то "неадекватно".

Что касается ranges - назрело давно, много было великов, один я даже приводил в "кладовой" (уничтожающая критика местных знатоков Улыбающийся). Но как range поможет схлопнуть тот же std::find который тупо требует пару итераторов ?
Записан
ksk-
Самовар
**
Offline Offline

Сообщений: 178



Просмотр профиля
« Ответ #9 : Январь 14, 2021, 12:16 »

Цитировать
Но как range поможет схлопнуть тот же std::find который тупо требует пару итераторов ?
https://en.cppreference.com/w/cpp/algorithm/ranges/find
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Январь 15, 2021, 12:00 »

Боюсь что эта вещь не предназначена для моих скромных целей (компактный вызов). И это лишь неск конкретных ф-ций

Кстати интересно, а зачем нужна std::ranges::find, почему не обойтись std::find или в чем разница? Судя по примеру реализации, в std::invoke. Немного копнул, да, познавательно, и наверное "небесполезно". Но не вижу ни одного примера в своих проектах где в этом нужда. В общем, "беллетристика" Улыбающийся
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #11 : Январь 24, 2021, 18:15 »

Вздох

Код:
const auto v = {4, 1, 3, 2};

if (auto result = ranges::find_if_not(v, is_even); result != v.end()) {
  std::cout << "First odd element in v: " << *result << '\n';
} else {
  std::cout << "No odd elements in v\n";
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Январь 25, 2021, 16:03 »

Вздох
Вы не замечали что перевод устойчивых буржуйских словечек неизменно уродлив? Так зачем самому повторять эту ошибку? Улыбающийся Хоть бы творчески переводили (по смыслу это  "эх")

Код:
const auto v = {4, 1, 3, 2};

if (auto result = ranges::find_if_not(v, is_even); result != v.end()) {
  std::cout << "First odd element in v: " << *result << '\n';
} else {
  std::cout << "No odd elements in v\n";
}
Не знаю можно ли (с новыми стандартами) записать v.begin/end, может в этом смысл? Но лаконичностью и выразительностью такой код точно не блещет (даже с калечным "v"). Так что нечего там (томно) вздыхать  Улыбающийся
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #13 : Январь 25, 2021, 16:39 »

Код:
ranges::find_if_not(v, is_even);

против

Код:
ranges::find_if_not(v.begin(), v.end(), is_even);

я даже не знаю что короче

что вам не нравится? итератор? ну напишите функцию, которая возвращает range (например, ленивый findAll), будете писать

Код:
if (auto result = findAll(v, is_even); !ranges::empty(result)) {
// do smth
}
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.174 секунд. Запросов: 22.