Есть ли способ неспецифически ссылаться на каждое значение на карте без использования цикла?C ++ - PullRequest
0 голосов
/ 13 июня 2019

У меня есть карта (ну, QMap, но я предполагаю, что если std: map имеет такую ​​же функциональность, как и в QMap), и я хочу получить доступ к каждому значению в ней сразу (чтобы вызвать функцию на все они. В частности, я пытаюсь получить доступ к QWidgets и вызывать setVisible(false) для всех из них).

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

Ответы [ 3 ]

0 голосов
/ 13 июня 2019

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

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

1) STL предоставляет std::for_each

2) но простой цикл делает его более удобным с for ( auto& x: m ) { x.second.Do(); }

Полный пример:

struct X
{
    int i;
    void Do() { std::cout << "Do called" << i << std::endl; }
};

int main()
{
    std::map<int, X> m;

    m[1]=X{10};
    m[3]=X{30};
    m[4]=X{40};

    std::for_each( m.begin(), m.end(), []( auto& x){ x.second.Do(); });

    // looks nicer for me:
    for ( auto& x: m ) { x.second.Do(); }
 }

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

0 голосов
/ 13 июня 2019

Да, вы можете использовать ranges::view::values, чтобы получить каждый второй элемент последовательности пар.

* 1006 Е.Г. *

QMap<Key, QWidget *> items; // filled somehow

auto widgets = items | ranges::view::values | ranges::view::indirect;
std::for_each(widgets.begin(), widgets.end(), [](auto & widget){ widget.setVisible(false); });
0 голосов
/ 13 июня 2019

Если у вас есть верхний предел для количества элементов, то вам не нужен цикл для вызова функции для всех элементов карты:

auto map = init_map();
auto it = std::begin(map);
if(it != std::end(map))
    (it++)->second.setVisible(false);
if(it != std::end(map))
    (it++)->second.setVisible(false);
if(it != std::end(map))
    (it++)->second.setVisible(false);
if(it != std::end(map))
    (it++)->second.setVisible(false);
if(it != std::end(map))
    (it++)->second.setVisible(false);
if(it != std::end(map))
    (it++)->second.setVisible(false);
if(it != std::end(map))
    (it++)->second.setVisible(false);
if(it != std::end(map))
    (it++)->second.setVisible(false);

Работает с картами до 8 элементов. Однако это довольно глупо и может быть значительно упрощено с помощью цикла. Вам не нужно писать цикл самостоятельно, поскольку вы можете использовать std::for_each, предоставляемый стандартной библиотекой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...