Es ist mein Verständnis, dass der Zweck std::vector::emplace_back()
speziell auf vermeiden ist eine Kopie Konstruktor aufrufen und stattdessen das Objekt direkt zu konstruieren.Warum Copykonstruktor wird in Aufruf aufgerufen std :: vector :: emplace_back()?
den folgenden Code vor:
#include <memory>
#include <vector>
#include <boost/filesystem.hpp>
using namespace std;
struct stuff
{
unique_ptr<int> dummy_ptr;
boost::filesystem::path dummy_path;
stuff(unique_ptr<int> && dummy_ptr_,
boost::filesystem::path const & dummy_path_)
: dummy_ptr(std::move(dummy_ptr_))
, dummy_path(dummy_path_)
{}
};
int main(int argc, const char * argv[])
{
vector<stuff> myvec;
// Do not pass an object of type "stuff" to the "emplace_back()" function.
// ... Instead, pass **arguments** that would be passed
// ... to "stuff"'s constructor,
// ... and expect the "stuff" object to be constructed directly in-place,
// ... using the constructor that takes those arguments
myvec.emplace_back(unique_ptr<int>(new int(12)), boost::filesystem::path());
}
Aus irgendeinem Grund, trotz der Verwendung der emplace_back()
Funktion schlägt fehl, diesen Code zu kompilieren, mit dem Fehler:
error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' [...] This diagnostic occurred in the compiler generated function 'stuff::stuff(const stuff &)'
Beachten Sie, dass der Compiler versucht, die Copykonstruktor zu erstellen (und benutzen). Wie ich oben beschrieben habe, ist es mein Verständnis, dass der Zweck von emplace_back()
-vermeiden ist die Verwendung des Copy-Konstruktor.
Natürlich, da der Compiler die Kopie Konstruktor zu erstellen und rufen versucht, gibt es keine Möglichkeit, den Code kompilieren würde selbst wenn ich den Kopierkonstruktor definiert für stuff
, weil die std::unique_ptr
nicht in einer Kopie verwendet werden kann, Konstrukteur. Daher würde ich sehr gerne die Verwendung eines Kopierkonstruktors vermeiden (tatsächlich muss ich es vermeiden).
(Dies ist VS 11.0.60610.01 Update 3 auf Windows 7 64-Bit)
Warum ist der Compiler Erzeugen, und versucht, die Copykonstruktor zu verwenden, auch wenn ich emplace_back()
nenne?
Hinweis (als Antwort auf @ Yakk Antwort):
Explizit den Umzug Konstruktor hinzufügen, wie folgt, löst das Problem:
stuff(stuff && rhs)
: dummy_ptr(std::move(rhs.dummy_ptr))
, dummy_path(rhs.dummy_path)
{}
@dannissenbaum beachten Sie, dass das Verschieben/Kopieren nicht in Ihrem Fall aufgerufen wird, muss aber für den Fall existieren, wo es bereits Inhalt in dem 'VECTOR' vorlag, wurde es erforderlich, um die Größe. Die Comple-Zeitinstanz der Methode weiß nicht, dass sie auf einem leeren "Vektor" aufgerufen wird, so dass sie alle Codepfade behandeln muss. – Yakk