When implementing the non-throwing swap idiom, should I use throw()?
namespace A
{
struct B
{
void swap( B& other ) throw()
{ /* fancy stuff that doesn't throw */ }
};
void swap( B& lhs, B& rhs ) throw()
{ lhs.swap(rhs); }
}
namespace std
{
template<>
void swap( A::B& lhs, A::B& rhs ) throw()
{ lhs.swap(rhs); }
}
In particular I worry about putting the throw() specification on the specialization of std::swap.
Bonus question:
Is the answer different when using C++0x’s noexcept keyword?
In C++03 you can put it there, but if it’s true that the fancy stuff doesn’t throw, it’s basically just documentation. It may or may not affect performance by adding the equivalent of
try / catch(...) { std::unexpected(); }around calls to the function: it’s up to the implementation whether it can do it without affecting performance.If you’re planning to use the
noexceptoperator (5.3.7) in C++0x, then suddenly it becomes worth having non-throwing exception specifications, so that the operator gives the “right” answer. I don’t really know what thenoexceptoperator is for, but if there’s a clever generic use for it, for example algorithms that become more efficient when something is non-throwing, then I guess it’s going to become necessary to mark functions as non-throwing, to get whatever the benefit is.For example:
Old style exception specifications (dynamic-exception-specification) are deprecated in C++0x (and pointless in C++03).