Warum ruft std::for_each auf einer Karte den Kopierkonstruktor auf?[Duplikat]
Frage
Ich habe das folgende einfache Beispiel, in dem ich anrufen möchte std::for_each
auf einer Sammlung von Objekten, die nicht kopierbar sind:
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 */ });
}
Wenn ich alles in ein std::vector
, es funktioniert wie erwartet, aber bei Verwendung von a std::map
, plötzlich std::for_each
möchte den (gelöschten) Kopierkonstruktor aufrufen.Warum?Ich wäre davon ausgegangen, dass ich lediglich einen Verweis auf das in der Karte gespeicherte Paar erhalte, ohne dass Kopien erforderlich sind.
Lösung
Das Problem ist, dass std::map
hat ein std::pair<const Key, Value>
als seinen internen Werttyp.Anstatt dies explizit anzugeben, können Sie in Standardbibliothekscontainern dies aus dem Containertyp extrahieren:
Machen Sie in C++11 dasselbe wie in C++98, aber Sie müssten darin ein Funktionsobjekt anstelle eines Lambda verwenden for_each
, und auch verwenden typedef
anstatt using =
):
using value_type = std::map<int, A>::value_type;
std::for_each(begin(m), end(m), [](value_type const& a) { /* do nothing */ });
Führen Sie in C++14 Folgendes aus:
std::for_each(begin(m), end(m), [](auto const& a) { /* do nothing */ });
Die Verwendung von auto
Inside the Lambda wird von Clang 3.4, Visual Studio 2013 November CTP und GCC 4.9 unterstützt.