Suppose i want to program a sink container for move only types. According to the discussion between Meyer and Sutter on http://scottmeyers.blogspot.de/2014/07/should-move-only-types-ever-be-passed.html the sink parameter should be passed by value and then moved into the member. But in terms of exception safety this sounds to me like a bad idea. When the constructor throws an exception, the value of the sink parameter is lost, while when i pass by rvalue reference and the exception happens before the actual move, the caller can still retrieve the value of the sink parameter.
Example below:
#include <memory>
#include <iostream>
#include <stdexcept>
using widget = std::unique_ptr<int>;
struct sink_1 {
sink_1(widget&& w) {
throw std::runtime_error("error");
w_ = std::move(w);
}
widget w_;
};
struct sink_2 {
sink_2(widget w) {
throw std::runtime_error("error");
w_ = std::move(w);
}
widget w_;
};
int main(int argc, char *argv[])
{
auto w1 = std::make_unique<int>(10);
auto w2 = std::make_unique<int>(20);
try {
sink_1 s1(std::move(w1));
} catch (std::runtime_error &e) {
std::cout << *w1 << std::endl;
}
try {
sink_2 s2(std::move(w2));
} catch (std::runtime_error &e) {
std::cout << *w2 << std::endl; // crashes
}
return 0;
}
Is this a valid and good design?