http://www.drdobbs.com/cpp/practical-c-error-handling-in-hybrid-env/197003350?pgno=4
In this article Herb Sutter explains that throwing an exception requires a copy
But modern C++ provides more feature: "Moving safely with move semantics & exception"
struct demo
{
demo() = default;
demo(const demo &) { cout << "Copying\n"; }
// Exception safe move constructor
demo(demo &&) noexcept { cout << "Moving\n"; }
private:
std::vector m_v;
};
int main()
{
demo obj1;
if (noexcept(demo(std::declval()))){ // if moving safe
demo obj2(std::move(obj1)); // then move it
}
else{
demo obj2(obj1); // otherwise copy it
}
demo obj3(std::move_if_noexcept(obj1)); // Alternatively you can do this----------------
return 0;
}
noexcept(T(std::declval())) to check if T’s move constructor exists and is noexcept in order to decide if we want to create an instance of T by moving another instance of T (using std::move). std::move_if_noexcept, which uses noexcept operator and casts to either rvalue or lvalue. Such checks are used in std::vector and other containers.std::move_if_noexcept which will move ownership of critical data only and only if move constructor is exception-safe.From: 7 best practices for exception handling in C++