Imagine I\'m writing some container template or something. And the time comes to specialize std::swap for it. As a good citizen, I\'ll enable ADL by doing somet
There is a similar problem for return types:
// Want to be compatible with both boost::tuple and std::tuple
template
auto first(Tuple&& tuple)
-> /* ??? */
{
// Introduce name into scope
using std::get;
// but ADL can still pick boost::get for boost::tuple
return get<0>(std::forward(tuple));
}
Using decltype( get<0>(std::forward isn't correct as get isn't in scope.
Possible workarounds are:
Introducing a dummy template (get in my example, swap in your case) in the enclosing scope; this includes putting the using std::swap declaration in the enclosing namespace, with the drawback of polluting the namespace.
Use of a type trait: typename std::tuple_element<0, typename std::remove_reference (actually this one is problematic but for reasons that don't belong here) in my example, and a potential is_nothrow_swappable in your case. Specializations then allow the template to be extended for other types if need be.