Я пытаюсь использовать SFINAE для создания оболочек вызовов функций, используя std :: result_of, чтобы получить возвращаемый тип функции. Небольшой образец для воспроизведения проблемы:std :: result_of failing for void return type
void test(int) {}
template<typename T, typename... Args, typename R = typename std::result_of<T(Args...)>::type, typename std::enable_if<!std::is_void<R>::value, int>::type* = nullptr>
int test2(R& ret_param, Args... args)
{
T* test_call = test;
ret_param = test_call(args...);
return 0;
}
template<typename T, typename... Args, typename std::enable_if<std::is_void<typename std::result_of<T(Args...)>::type>::value, int>::type* = nullptr>
int test2(Args... args)
{
T* test_call = test;
test_call(args...);
return 0;
}
int main()
{
test2<decltype(test)>(1);
}
компиляции это с GCC 4.9.2 результатов:
68:26: error: no matching function for call to 'test2(int)'
68:26: note: candidates are:
46:5: note: int test2(R&, Args ...) [with T = void(int); Args = {}; R = int; typename std::enable_if<(! std::is_void<R>::value), int>::type* <anonymous> = 0u]
46:5: note: no known conversion for argument 1 from 'int' to 'int&'
56:5: note: template<class T, class ... Args, typename std::enable_if<std::is_void<typename std::result_of<_Functor(_ArgTypes ...)>::type>::value, int>::type* <anonymous> > int test2(Args ...)
56:5: note: template argument deduction/substitution failed:
55:142: error: function returning a function
55:142: note: invalid template non-type parameter
тогда Проблема заключается в том, что какой-то образом «имяТип станд :: result_of :: типа» оценивает к функция возвращает функцию? Каков правильный способ использования SFINAE для принудительного разрешения перегрузки для выбора другой функции, если тип возврата функции шаблона недействителен? Стоит упомянуть, что в обратном случае, когда тестовая функция возвращает int. Кроме того, если enable_if удаляется для разрешения std :: is_void, он будет работать в этом случае (но очевидно, что тогда обе функции будут иметь правильное разрешение, если есть тип возврата, и компиляция завершится неудачно, когда он выбирает тот, который не ожидает возвращаемого значения).
В качестве начала 'decltype (test)' является типом функции, и вы привязываете это к 'T', которое в логике включения рассматривается как возвращаемый тип. –
Я бы использовал 'class' вместо' typename', и я бы избегал этих многосотни символов. Попытайтесь разделить вещи естественно, чтобы быть читаемыми. –
Не следует, я понимаю, что std :: result_of :: type - это тип возвращаемого значения функции T, если вызывается с аргументами Args ... что я использую в логике включения. –
Grahalt