How do I write an ADL-enabled trailing return type, or noexcept specification?
I think I would move it into a separate namespace
namespace tricks {
using std::swap;
template <typename T, typename U>
void swap(T &t, U &u) noexcept(noexcept(swap(t, u)));
}
template <typename T>
void swap(my_template<T>& x, my_template<T>& y)
noexcept(noexcept(tricks::swap(std::declval<T>(), std::declval<T>())))
{
using std::swap;
swap(x.something_that_is_a_T, y.something_that_is_a_T);
}
Alternatively you can move the whole code up into tricks
and delegate to there.
Determining return type of generic function
Use a separate namespace, where you can put the using clause. This prevents the namespace pollution, since the using clause only applies to that namespace. I would recommend naming it something unique, so you don't accidentally spread it around.
namespace transmog_detail
{
using std::abs;
template<class T>
auto transmogrify(T x) -> decltype(abs(x) + 2.0)
{
return abs(x) + 2.0;
}
}
// Then pull it into the current namespace, as recommended by @LucDanton.
using transmog_detail::transmogrify;
// Or if there is a reason, you can forward.
// template<class T>
// auto transmogrify(T x)
// -> decltype(transmog_detail::transmogrify(x))
// {
// return transmog_detail::transmogrify(x);
// }
`decltype` and mixing ADL-lookup with non-ADL-lookup
You can use a detail namespace and some wrapping:
namespace detail {
using std::sin;
template<typename T>
auto foo(T f) -> decltype(sin(f)) { return sin(f); }
}
template<typename T>
auto foo(T f) -> decltype(detail::foo(f)) { return detail::foo(f); }
C++ noexcept specification depending on data members
std::declval<T>()
simulates an rvalue T
instance. std::declval<T&>()
simulates an lvalue T
instance. Use this in place of T()
.
ADL in constructor initialization list
You can solve this directly from within the initialiser list, by using a lambda expression: it allows you to write the required helper function inline, and that helper function can contain using std::abs;
.
template<typename T>
struct Foo
{
T _data;
Foo(T data):
_data([&](){ using std::abs; return abs(data); }())
{}
};
Why are is_swappable and is_nothrow_swappable not included in C++11?
is_swappable<T>
and is_nothrow_swappable<T>
were never proposed for C++11. That is the main reason they aren't in C++11. I.e. nothing gets in without being proposed.
So why weren't these proposed?
Speaking from personal experience, I don't propose anything that I haven't implemented and found useful. And though I did implement them for libc++, I did not do so prior to C++11 being published. I simply did not have the time and tools to do so for C++11. My best guess is that this was true of any one else.
Glad you found these useful. You could be the one to propose them for the next C++ standard! Seriously! We need your help!
Update
In response to:
it's a bit of a hack though, because this is only works if swap is
implemented in terms of the Move Constructors and Assignment Operators
Here's test indicating how it behaves on libc++'s implementation:
#include <type_traits>
#include <iostream>
struct A
{
A(const A&);
};
struct B
{
};
void swap(B&, B&);
struct C
{
};
void swap(C&, C&) noexcept;
struct D
{
D(const D&) noexcept;
D& operator=(const D&) noexcept;
};
int main()
{
std::cout << "std::__is_nothrow_swappable<int>::value = "
<< std::__is_nothrow_swappable<int>::value << '\n';
std::cout << "std::__is_nothrow_swappable<A>::value = "
<< std::__is_nothrow_swappable<A>::value << '\n';
std::cout << "std::__is_nothrow_swappable<B>::value = "
<< std::__is_nothrow_swappable<B>::value << '\n';
std::cout << "std::__is_nothrow_swappable<C>::value = "
<< std::__is_nothrow_swappable<C>::value << '\n';
std::cout << "std::__is_nothrow_swappable<D>::value = "
<< std::__is_nothrow_swappable<D>::value << '\n';
}
Which for me outputs:
std::__is_nothrow_swappable<int>::value = 1
std::__is_nothrow_swappable<A>::value = 0
std::__is_nothrow_swappable<B>::value = 0
std::__is_nothrow_swappable<C>::value = 1
std::__is_nothrow_swappable<D>::value = 1
Related Topics
How to Make the for Each Loop Function in C++ Work with a Custom Class
Get Current Working Directory in a Qt Application
How to Use Lambda Auto Parameters in C++11
Is There a Null Std::Ostream Implementation in C++ or Libraries
How to Use Cmake_Export_Compile_Commands
Instantiate Class with or Without Parentheses
Why Don't I Need to Specify "Typename" Before a Dependent Type in C++20
What Happens When Queryperformancecounter Is Called
Command Line Compile Using Cl.Exe
How to Catch Out of Memory Exception in C++
Warning C4003 and Errors C2589 and C2059 On: X = Std::Numeric_Limits<Int>::Max();
Std Linker Error with Apple Llvm 4.1
What Exactly Is Va_End For? Is It Always Necessary to Call It
Do Stl Maps Initialize Primitive Types on Insert
Node Packages Not Building on Windows 8.1 - Missing Microsoft.Cpp.Default.Props
When Do You Prefer Using Std::List<T> Instead of Std::Vector<T>