Это самое близкое, что я дошел до этого: определите функцию, возвращающую таблицы разных размеров, и ваш результат sizeof(select(...))
получит указатель на функцию, которую вы хотите сопоставить.Чтобы гарантировать, что код будет компилироваться, даже если функция не существует в данном классе, вы можете использовать отдельную проверку has_function
.
Результат разрешения перегрузки находится в select<has_function<T>::value, T>::value
.
С этимкод, который вы можете даже «разрешить» для элементов данных, а не только для функций, это только вопрос выбора правильного параметра для функции выбора.
Однако здесь есть один недостаток - разрешение перегрузки зависит не от параметров функции, а от функциитип.Это означает, что не происходит никакого обычного преобразования типов параметров.
// Verify the name is valid
template <typename T>
struct has_function
{
struct F {int function;};
struct D : T, F {};
template <typename U, U> struct same_;
template <typename C> static char(&select_(same_<int F::*, &C::function>*))[1];
template <typename> static char(&select_(...))[2];
enum {value = sizeof(select_<D>(0)) == 2};
};
// Values to report overload results
enum type { none=1 , function_sz_size_t , function_sz , function_string };
template <bool, typename R> struct select;
template <typename R> struct select<false, R>
{
enum {value = none};
};
template <typename R> struct select<true, R>
{
// Define your overloads here, they don't have to be templates.
template <typename Ret, typename Arg> static char(&select_(Ret (R::*)(const char*, Arg)))[function_sz_size_t];
template <typename Ret, typename Arg> static char(&select_(Ret (R::*)(Arg)))[function_sz];
template <typename Ret> static char(&select_(Ret (R::*)(std::string)))[function_string];
template <typename Ret> static char(&select_(Ret (R::*)(std::string&&)))[function_string];
template <typename Ret> static char(&select_(Ret (R::*)(const std::string&)))[function_string];
static char(&select_(...))[none];
enum {value = sizeof(select_(&R::function))};
};