I am writing an application that needs to store objects of a class that uses the PIMPL idiom in a std::vector
. Because the class uses std::unique_ptr
to store a pointer to it's implementation and std::unique_ptr
is not copyable, the class itself is not copyable. std::vector
should still work in this case because the class is still movable.
To avoid creating a copy I tried using emplace_back
to construct the elements directly into the vector
, but for some reason it still complains that it is trying to call the copy constructor!
I've written a simple example to demonstrate the problem.
test.h:
#pragma once
#include <memory>
// Simple test class implemented using the PIMPL (pointer to implementation) idiom
class Test
{
public:
Test(const int value);
~Test();
void DoSomething();
private:
// Forward declare implementation struct
struct Impl;
// Pointer to the implementation
std::unique_ptr<Impl> m_impl;
};
test.cpp
#include "test.h"
#include <iostream>
// Implementation struct definition
struct Test::Impl
{
Impl(const int value)
: m_value(value)
{}
void DoSomething()
{
std::cout << "value = " << m_value << std::endl;
}
private:
int m_value;
};
// Construct the class and create an instance of the implementation struct
Test::Test(const int value)
: m_impl(std::make_unique<Impl>(value))
{}
Test::~Test() = default;
// Forward function calls to the implementation struct
void Test::DoSomething()
{
m_impl->DoSomething();
}
main.cpp:
#include "test.h"
#include <vector>
int main()
{
std::vector<Test> v;
// Even though I'm using "emplace_back" it still seems to be invoking the copy constructor!
v.emplace_back(42);
return 0;
}
When I try to compile this code I get the following error:
error C2280: 'Test::Test(const Test &)': attempting to reference a deleted function
This leads to two questions...
-
Why is it attempting to use the copy constructor even though I explicitly used
emplace_back
? -
How can I get this to compile without errors? The object is movable so according to the standard it should be able to be stored in a
std::vector
.
Aucun commentaire:
Enregistrer un commentaire