Fw: An omnipotant swap?
#include <list>
namespace omni{
template <class T, T val>
struct member_wrapper{};
template <class T>
char test_for_swap(const T&, member_wrapper<void (T::*)(T&), &T::swap>* p = 0);
template <class T>
double test_for_swap(const T&, ...);
template <class T>
struct has_member_swap
{
static T t;
static const bool value = (1 == sizeof(test_for_swap(t)));
};
//BOOST_STATIC_ASSERT(has_member_swap<std::list<int>::value);
//BOOST_STATIC_ASSERT(!has_member_swap<int>::value);
//BOOST_STATIC_ASSERT(!has_member_swap<noswap>::value);
template<bool b>
struct swapper
{
template <class T>
static void swap(T& t1, T& t2)
{ std::swap(t1, t2); }
};
template<>
struct swapper<true>
{
template <class T>
static void swap(T& t1, T& t2)
{ t1.swap(t2); }
};
template <class T>
void swap(T& t1, T& t2)
{
swapper<has_member_swap<T>::value>::swap(t1, t2);
}
} // namespace omni
struct noswap{};
int main()
{
std::list<intl1, l2;
omni::swap(l1, l2);
noswap s1, s2;
omni::swap(s1, s2);
int i1, i2;
omni::swap(i1, i2);
return 0;
}
Используется фича компиляторов
"Substitution Failure Is Not An Error" (SFINAE), на основе которой в boost'e сейчас разрабатывается инструмент
enable_if.