Почему std::for_each на карте вызывает конструктор копирования?[дубликат]

StackOverflow https://stackoverflow.com//questions/21016149

Вопрос

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

class A {
public:
    A() : x(0) {}
    A(const A&) = delete;

private:
    int x;
};

void func() {
    std::vector<A> v(10);
    std::map<int, A> m;

    // works as expected
    std::for_each(begin(v), end(v), [](const A& a) { /* do nothing */ });

    // error calling copy constructor
    std::for_each(begin(m), end(m), [](const std::pair<int, A>& a) { /* do nothing */ });
}

Если я положу все в std::vector, он работает так, как я ожидал, но при использовании std::map, внезапно std::for_each хочет вызвать (удаленный) конструктор копирования.Почему?Я бы предположил, что просто получаю ссылку на пару, сохраненную на карте, без каких-либо необходимых копий.

Это было полезно?

Решение

Проблема в том, что std::map имеет std::pair<const Key, Value> как его внутренний тип значения.Вместо того, чтобы явно указывать это, контейнеры стандартной библиотеки позволяют вам извлечь это из типа контейнера:

В C++11 сделайте это (так же, как и в C++98, но вам придется использовать объект функции, а не лямбду внутри for_each, а также использовать typedef вместо using =):

using value_type = std::map<int, A>::value_type;
std::for_each(begin(m), end(m), [](value_type const& a) { /* do nothing */ });

В С++ 14 выполните:

std::for_each(begin(m), end(m), [](auto const& a) { /* do nothing */ });

Использование auto внутри лямбды поддерживается Clang 3.4, Visual Studio 2013, ноябрь CTP и GCC 4.9.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top