class openfile {
FILE* f;
public:
explicit openfile(const char* filename) : f(std::fopen(filename, "rw")){
if(!f){throw std::runtime_error("unable to open file");}
}
~openfile(){fclose(f);}
void write(const char* message);
// copy suppressed
};Where should f point if openfile has been moved from?
If the class wants to support move semantic, it has to change it’s invariants.
As a copy is a valid move implementation, moves are not necessarily cheaper than copies
std::vector<std::string> create() {
std::vector<std::string> coll;
coll.reserve(3);
// ...
coll.push_back(s+s); // because of push_back(T&&) and std::string(std::string&&);
coll.push_back(std::move(s)); // because of push_back(T&&) and std::string(std::string&&);
return coll; // because of std::vector<T>(std::vector<T>&&) and std::string(std::string&&);
}-
returning locals by value is cheap
-
temporaries (unnamed) are cheap
-
it is possible to "mark" manually a value as temporary
Simpliciteness: it is possible to return uncopyable (but moveable) types from function without adding further indirections.
struct type_with_costly_or_no_copy_constructor{ /* ... */};
// allocates unnecessarily (which is a costly operation) to avoid a potential copy
// should the caller check for nullptr?
// does it point to one or more elements?
// is the pointed content shared with someone else?
// is it an owning pointer?
// should the caller free it? If yes, how?
type_with_costly_or_no_copy_constructor* factory();
// no overhead, less documentation needed, no leaks by design
type_with_costly_or_no_copy_constructor factory();Correctness: before C++11 it was not possible to implement something like std::unique_ptr.
It’s C++03 counterpart, std::auto_ptr has been declared as broken beyond repair.
It’s copy constructor does not copy, so, for example, it’s not safe to use with stl algorithms, containers and other functions.
// suppose that all pointer are != nullptr
std::auto_ptr<int> v[N] = { /* ... */ };
std::sort(v, v + N,
[](const std::auto_ptr<int>& lhs, const std::auto_ptr<int>& rhs){
return *lhs < *rhs;
}); // might crash if sort makes an internal temporary copy