Я искал для установки приоритетов на перекрывающихся enable_if, особенно для возврата к вызову методов контейнера STL, где мои черты были такими вещами, как is_assignable is_insterable и т. Д., С которыми есть перекрытие на ряде контейнеров.
Я хотел бы расставить приоритеты для assign, если он существует, иначе используйте итератор вставки. Это общий пример того, что я придумал (модифицированный с бесконечными уровнями приоритета некоторыми удобными людьми в канале #boost irc). Это работает, поскольку неявное преобразование уровня приоритета ранжирует перегрузку ниже другого, что в противном случае является одинаково допустимым вариантом - устранение неоднозначности.
#include <iostream>
#include <string>
template <std::size_t N>
struct priority : priority<N - 1> {};
template <>
struct priority<0> {};
using priority_tag = priority<2>;
template <typename T>
void somefunc(T x, priority<0>)
{
std::cout << "Any" << std::endl;
}
template <typename T>
std::enable_if_t<std::is_pod<T>::value >
somefunc(T x, priority<2>)
{
std::cout << "is_pod" << std::endl;
}
template <typename T>
std::enable_if_t<std::is_floating_point<T>::value >
somefunc(T x, priority<1>)
{
std::cout << "is_float" << std::endl;
}
int main()
{
float x = 1;
somefunc(x, priority_tag{});
int y = 1;
somefunc(y, priority_tag{});
std::string z;
somefunc(z, priority_tag{});
return 0;
}
Было также предложено, чтобы в C ++ 14 я мог просто использовать constexpr if, чтобы достичь той же цели, что было бы намного чище, если бы Visual Studio 2015 их поддерживал. Надеюсь, это поможет кому-то еще.
#include <iostream>
#include <string>
template <typename T>
void somefunc(T x)
{
if constexpr(std::is_floating_point<T>::value) {
static_assert(std::is_floating_point<T>::value);
std::cout << "is_float" << std::endl;
} else if constexpr(std::is_pod<T>::value) {
static_assert(std::is_pod<T>::value);
std::cout << "is_pod" << std::endl;
} else {
static_assert(!std::is_floating_point<T>::value);
static_assert(!std::is_pod<T>::value);
std::cout << "Any" << std::endl;
}
}
int main()
{
float x = 1;
somefunc(x);
int y = 1;
somefunc(y);
std::string z;
somefunc(z);
return 0;
}
// благодаря k-balloon @ #boost!