I have a class that stores a large std::map. My understanding is that the idiomatic way to do this is:
class Foo {
public:
Foo(/* Note: passed by value */ std::map<Bar, Baz> large_map) : large_map_(std::move(large_map)) {}
private:
std::map<Bar, Baz> large_map_;
};
int main() {
std::map<Bar, Baz> large_map;
// Work hard to initialize large_map.
Foo foo = Foo(std::move(large_map));
}
This transfers the ownership of large_map from main, to the constructor arg and then to Foo's member. The problem with this is that the code is hard to use properly and I discovered that someone somewhere created a Foo and forgot to move the map into the ctor:
void deep_dark_hidden_code() {
std::map<Bar, Baz> large_map;
// Work hard to initialize large_map.
Foo foo = Foo(large_map); // Whoops! The author of this code forgot to std::move
}
I am looking for a way to write Foo which protects against such mistakes. My first thought was to use unique_ptr
class Foo {
public:
Foo(std::unique_ptr<std::map<Bar, Baz>> large_map_ptr) : large_map_(std::move(*large_map_ptr)) {}
private:
std::map<Bar, Baz> large_map_;
};
int main() {
std::unique_ptr<std::map<Bar, Baz>> large_map_ptr = new std::map<Bar, Baz>;
// Work hard to initialize large_map_ptr.
Foo foo = Foo(std::move(large_map_ptr));
}
This code is essentially using unique_ptr as a hack to erase the copy constructor of std::map. My question is whether there is a more explicit way to do this. Some magic template make_uncopyable like:
class Foo {
public:
Foo(make_uncopyable<std::map<Bar, Baz>> large_map) : large_map_(std::move(large_map)) {}
private:
std::map<Bar, Baz> large_map_;
};
The desired effect is to leave the code in my main intact but prevent the code in deep_dark_hidden_code from compiling.