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.