LINUX.ORG.RU

Ответ на: комментарий от Torvus

Это понятно. Вопрос в том, что у меня 3-4 контейнера. Для каждого foreach? Или есть варианты красивее?

UVV ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Параллельно или последовательно?

В данном контексте пофигу.

У меня была мысль сделать что-то типа QVector<MyClass, ClassTypeEnum>, тем самым объединив все в один, но тогда придётся разделать их, когда мне нужна операция только над одним типом элементов, что нужно довольно часто.

UVV ★★★★★
() автор топика

Если тебе не нужна параллельность, в чем вообще смысл вопроса? Ну пройдись по каждому for и все.

CatsCantFly
()

Тебе нужен интрусивный контейнер

yoghurt ★★★★★
()
Ответ на: комментарий от UVV

Вопрос в том, что у меня 3-4 контейнера. Для каждого foreach?

for( auto& v : { v1, v2, v3, v4 } ) {
    for( auto& o : v ) {
        ...
    }
}

В Qt CoW потому { v1, v2, v2, v2 } будет быстрым.

anonymous
()
Ответ на: комментарий от anonymous

А вот это уже интересно..

UVV ★★★★★
() автор топика
Ответ на: комментарий от anonymous

А что не так с ними?

UVV ★★★★★
() автор топика
Ответ на: комментарий от UVV

В том, что никто не понял, что тебе нужно. И, похоже, тебе была нужна какая-то банальность дошкольного уровня, о которой лично я постеснялся бы спрашивать.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ну я не такой крутой как ты, чтобы знать дошкольные вещи, поэтому спрашивать не стесняюсь.

UVV ★★★★★
() автор топика

Запихивай нужные действия в лямбду или обычную функцию, затем std::for_each по каждому контейнеру.

equeim ★★
()
Ответ на: комментарий от UVV

тебе была нужна какая-то банальность дошкольного уровня, о которой лично я постеснялся бы спрашивать.

Ну я не такой крутой как ты

фейспалм.

Напиши функцию и вызови ее 3 раза. Или это тоже слишком круто?

tailgunner ★★★★★
()
Ответ на: комментарий от UVV

Тогда, если возьмешь вариант с { v1, v2, v3, v4 }, ты должен понимать что такое CoW и что именно будет происходить:

http://doc.qt.io/qt-5/implicit-sharing.html

Чтоб потом не было новых вопросов. Впрочем это в любом случае стоит прочитать, если пользуешься Qt.

anonymous
()
Ответ на: комментарий от anonymous

Действительно, такой вариант выглядит логичнее.

equeim ★★
()

В шаблоны не учили что-ли?

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

template<typename... Args>
void pass(const Args&...) {}

template <class F, class... Args>
void multiforeach(F&& function, const Args&... args) {
    pass(std::for_each(args.begin(), args.end(), function)...);
}

int main() {
    std::vector<std::string> a = { "a1", "a2" };
    std::vector<std::string> b = { "b1", "b2" };
    std::vector<std::string> c = { "c1", "c2" };

    multiforeach([](const std::string& s){std::cerr << s << std::endl;},a, b, c, std::vector<std::string>{"d1", "d2"});

    return 0;
}

Можно и рекурсивно:

template <class F>
void multiforeach(F&&) {
}

template <class F, class C, class... More>
void multiforeach(F&& function, const C& container, const More&... more) {
    std::for_each(container.begin(), container.end(), function);
    multiforeach(function, more...);
}
slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от slovazap

Если уж прикручивать шаблоны, то чтоб упрощать запись:

#include <iostream>
#include <memory>
#include <type_traits>
#include <vector>
using namespace std;


template <class T>
struct container {
    virtual ~container() {}
    virtual size_t size() const = 0;
    virtual T& operator[]( size_t index ) = 0;
};

template <class T>
struct container_imp : public container<typename T::value_type> {
    container_imp( T& c ) : c_( c ) {}
    size_t size() const override { return c_.size(); }
    typename T::value_type& operator[]( size_t index ) override { return c_[ index ]; }

    T& c_;
};

template<class T>
struct join_iterator {
    void operator++( void ) { ++index_; }
    bool operator!=( const join_iterator& it ) const { return index_ != it.index_; }

    T& operator*( void ) const {
        size_t off = index_;
        for( auto& c : containers_ ) {
            const size_t size = c->size();
            if( off < size )
                return (*c)[ off ];

            off -= size;
        }

        throw out_of_range( "AAAA!!!!!" );
    }

    vector<unique_ptr<container<T>>>& containers_;
    size_t index_;
};

template <class T>
struct join_iterators_helper
{
    join_iterators_helper() {}

    template<class U, class... Args>
    join_iterators_helper( U&& c, Args&&... args )
    :
        join_iterators_helper( std::forward<Args>( args )... )
    {
        containers_.emplace( containers_.begin(), new container_imp<typename decay<U>::type>( c ) );
        count_ += c.size();
    }

    join_iterator<T> begin( void ) { return { containers_, 0 }; }
    join_iterator<T> end( void ) { return { containers_, count_ }; }

    vector<unique_ptr<container<T>>> containers_;
    size_t count_ = 0;
};

template <class T, class... Args>
auto join_iterators( T&& first, Args&&... args ) {
    return join_iterators_helper<typename decay<T>::type::value_type>( std::forward<T>( first ), std::forward<Args>( args )... );
}


int main() {
    vector<string> a { "a1", "a2" };
    vector<string> b { "b1", "b2" };
    vector<string> c { "c1", "c2" };

    for( string& s : join_iterators( a, b, c ) )
        cout << s << '\n';
}

П.С. код - говно, но писалось для примера использования, а не реализации.

anonymous
()

Это топик о том, как сделать простое действие наиболее сложными и идиотским способом?

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Нeт, так что можeшь проходить мимо.

anonymous
()
Ответ на: комментарий от andreyu

Это топик о том, как сделать простое действие наиболее сложными и идиотским способом?

Здесь целое соревнование на эту тему.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Т.е. ты считаешь, что если бы была возможность писать:

for( string& s : join( a, b, c ) )
    cout << s << '\n';

Она была бы идиотской (про реализацию я и сам высказался, она тут приведена только для компилябельности примера)? ИМХО, для ТС это было как раз то, что он хочет. Или ты считаешь свои ненужные комментарии выше чем-то лучшим?

anonymous
()
Ответ на: комментарий от anonymous

Или ты считаешь свои ненужные комментарии выше чем-то лучшим?

Я считаю, что ТС нужно было написать функцию и вызвать ее 3 раза. Всё. А написание универсальных средств сцепления контейнеров для задачи ТС - это именно соревнование в ненужности.

tailgunner ★★★★★
()

Раз уж у вас тут контест, попробую и я свои силы.

QVectorIterator<Что-то> it1(v1), it2(v2), it3(v3);
while (it1.hasNext() && it2.hasNext() && it3.hasNext())
{
    i = it1.next();
    j = it2.next();
    k = it3.next();
}

PS. сварщик не настоящий

d_a ★★★★★
()
Ответ на: комментарий от tailgunner

Я считаю, что ТС нужно было написать функцию и вызвать ее 3 раза.

И ты неправ. Во-первых в С++ есть лямбды. Во-вторых возможно ему подошел бы вариант с одним дополнительным циклом, чтоб было бы и проще и компактней.

anonymous
()
Ответ на: комментарий от tailgunner

Кроме того, отдельная функция имеет другую область видимости, и дополнительные данные туда пришлось бы отдельно передавать.

anonymous
()
Ответ на: комментарий от anonymous

Я считаю, что ТС нужно было написать функцию и вызвать ее 3 раза.

И ты неправ

И я прав - не нужно бессмысленной маст^Wакробатики сцепления контейнеров.

Во-первых в С++ есть лямбды.

Функция старого стиля или нечто, преобразуемое к std::function - не принципиально. Выбирается в зависимости от количества нужных локальных переменных.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 2)
Ответ на: комментарий от anonymous

Она была бы идиотской?

Да. Это С++, тут не принято делать новую коллекцию из 4-х старых чтобы просто перебрать элементы. А то что ты описал - это удел хипстерских языков.

dnf83
()
Ответ на: комментарий от tailgunner

Функция старого стиля или нечто, преобразуемое к std::function - не принципиально.

Как всегда виляешь хвостом, не умея в практику и конкретику.

anonymous
()
Ответ на: комментарий от tailgunner

не нужно бессмысленной маст^Wакробатики сцепления контейнеров.

На практике - да. Но ТС это никто и не советовал в качестве решения.

anonymous
()
Ответ на: комментарий от anonymous

Функция старого стиля или нечто, преобразуемое к std::function - не принципиально.

Как всегда виляешь хвостом

Я обычно не считаю собеседников глупее себя. В данном случае я считал, что ты тоже понимаешь, когда использовать обычную функцию, а когда лямбду.

не умея в практику и конкретику.

Ну да, только ты и умеешь программировать.

Но ТС это никто и не советовал в качестве решения.

Пройтись по контейнерам одного типа (комментарий)

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)

Тред достоин перепоста на govnokod.ru.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от tailgunner

Я обычно не считаю собеседников глупее себя. В данном случае я считал, что ты тоже понимаешь, когда использовать обычную функцию, а когда лямбду.

В С++ лямбда - не функция, а объект. В том числе лямбды не попадают под определение функции и в стандарте.

Ну да, только ты и умеешь программировать.

Да нет, почти все умеют, дело нехитрое. Вот ТС, к примеру, умеет, т.к. видно, что человек решает какие-то задачи, а не просто умничает.

anonymous
()
Ответ на: комментарий от anonymous

В С++ лямбда - не функция, а объект

Окей, это всё меняет. Ты победил.

tailgunner ★★★★★
()
Ответ на: комментарий от andreyu

не сложным и идиотским, а модным и хипстерским, чтобы букаф было поменьше. а на оптимизацию, по ходу, всем пофигу. начитались про коров, лямбды и рады по уши.
суровая оптимизация не выглядит красиво. и не делается автоматически. впрочем, о чём это я?

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Ответ на: комментарий от andreyu

И тем не менее:

QList<QPointer<QWidget>> bodies  { ... };
QList<QPointer<QWidget>> footers { ... };
QList<QPointer<QWidget>> headers { ... };

...

// Выполнить для каждого:
if( w ) {
    w->hide();
    w->deleteLater();
}

Как запишешь? Мой вариант был:

for( auto l : { bodies, footers, headers } ) {
    for( auto w : l ) {
        if( w ) {
            w->hide();
            w->deleteLater();
        }
    }
}

Но видно он слишком глупый и сложный.

anonymous
()
Ответ на: комментарий от Iron_Bug

а на оптимизацию, по ходу, всем пофигу. начитались про коров, лямбды и рады по уши.

Оптимизировать надо узкие места, а остальные писать так, «чтобы букаф было поменьше». А в обе крайности кидаются только идиоты.

anonymous
()

Вставлю своих пять грошей.

1) Если есть полиморфизм, то создаем дополнительный контейнер и бегаем вначале по нему, потом по элементам каждого.

2) Макрос.

3) Темплейтная функция.

3) Вариадик темплейт.

Booster ★★
()
Последнее исправление: Booster (всего исправлений: 1)
Ответ на: комментарий от Iron_Bug

суровая оптимизация не выглядит красиво. и не делается автоматически

...и обычно нафиг не нужна.

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.