
On Apr 3, 2012, at 1:44 PM, Dave Abrahams wrote:
on Tue Apr 03 2012, Howard Hinnant <howard.hinnant-AT-gmail.com> wrote:
That's lovely, but... exactly how does noexcept play into the metaprogramming picture?
For example, I used it to create an is_nothrow_swappable<A> trait (http://llvm.org/svn/llvm-project/libcxx/trunk/include/type_traits) so that I could write:
struct B { A a; };
void swap(B& x, B& y) noexcept(__is_nothrow_swappable<A>::value) { swap(x.a, y.a); }
instead of:
using std::swap; void swap(B& x, B& y) noexcept( noexcept( swap(declval<A&>(), declval<A&>()))) { swap(x.a, y.a); }
The latter gets very tedious when B has several members and/or bases.
But isn't this a better way to relieve the tedium?
#define RETURNS(...) \ noexcept(noexcept(decltype(__VA_ARGS__)(std::move(__VA_ARGS__)))) \ -> decltype(__VA_ARGS__) \ { return (__VA_ARGS__); } \ typedef int RETURNS_CAT(RETURNS_, __LINE__)
#define RETURNS_CAT_0(x, y) x ## y #define RETURNS_CAT(x, y) RETURNS_CAT_0(x,y)
...
auto swap(B& x, B& y) RETURNS(swap(x.a,y.a), swap(x.b,y.b), ...);
I hadn't seen that one before. I guess Bjarne isn't getting rid of the preprocessor yet... Howard