Reputation: 22267
I wonder if I understood emplace_back
correctly
#include <vector>
using namespace std;
struct Hero {
Hero(const string&) {}
Hero(const char*) {}
Hero(int) {}
// forbid a clone:
Hero(const Hero&) = delete;
Hero& operator=(const Hero&) = delete;
};
int main() {
vector<Hero> heros1 = { "Bond", "Hulk", "Tarzan" }; // ERR: copies?
vector<Hero> heros;
heros.emplace_back( 5 ); // ERR: copies
heros.emplace_back( string("Bond") ); // ERR: copies
heros.emplace_back( "Hulk" ); // ERR: copies
}
Thus, I am really wondering If I understood emplace_back
incorrectly: I though it would prevent to make a copy of Hero
, because it creates the Item in-place.
Or is it a implementation error in my g++-4.7.0?
Upvotes: 10
Views: 3034
Reputation: 20609
You need to define a move constructor and move-assignment operator, like this:
struct Hero {
Hero(const string&) {}
Hero(const char*) {}
Hero(int) {}
Hero(Hero&&) {}
Hero& operator=(Hero&&) { return *this; }
// forbid a clone:
Hero(const Hero&) = delete;
Hero& operator=(const Hero&) = delete;
};
This allows values of type Hero to be moved into the function. Move is usually faster than copy. If the type is neither copyable nor movable then you cannot use it in a std::vector
.
Upvotes: 6
Reputation: 22267
Uh... I got it.
If I forbit to copy the Hero
s, I must allow them to move, if I want to put them in containers. How silly of me.
struct Hero {
Hero(const string&) {}
Hero(const char*) {}
Hero(int) {}
// no clone:
Hero(const Hero&) = delete;
Hero& operator=(const Hero&) = delete;
// move only:
Hero(Hero&&) {}
Hero& operator=(Hero&&) {}
};
And all examples except for the initializer list work.
Upvotes: 3
Reputation: 146910
It's no implementation error- you did not provide a move constructor.
Upvotes: 4