Самый простой способ определить тип возвращаемого значения функции - PullRequest
0 голосов
/ 07 декабря 2018

Учитывая очень простую, но длинную функцию, такую ​​как:

int foo(int a, int b, int c, int d) {
    return 1;
}

// using ReturnTypeOfFoo = ???

Какой самый простой и краткий способ определить тип возвращаемого значения функции (ReturnTypeOfFoo, в этом примере: int) во время компиляции без повторения типов параметров функции (только по имени, поскольку известно, что функция не имеет никаких дополнительных перегрузок)?

Ответы [ 3 ]

0 голосов
/ 07 декабря 2018

Я не знаю, является ли самый простой способ (если вы можете использовать C ++ 17, конечно, нет: см. Ответ NathanOliver), но ... как насчет объявления функции следующим образом:

template <typename R, typename ... Args>
R getRetType (R(*)(Args...));

и с использованием decltype()?

using ReturnTypeOfFoo = decltype( getRetType(&foo) );

Обратите внимание, что getRetType() только объявлен и не определен, поскольку вызывается только decltype(), поэтому релевантным является только возвращаемый тип.

0 голосов
/ 07 декабря 2018

Здесь вы можете использовать std::function, что даст вам typedef для типа возвращаемого значения функции.Для этого требуется поддержка C ++ 17, так как он опирается на вычет аргумента шаблона класса , но он будет работать с любым вызываемым типом:

using ReturnTypeOfFoo = decltype(std::function{foo})::result_type;

Мы можем сделать этонемного более общий, как

template<typename Callable>
using return_type_of_t = 
    typename decltype(std::function{std::declval<Callable>()})::result_type;

, который затем позволяет использовать его как

int foo(int a, int b, int c, int d) {
    return 1;
}

auto bar = [](){ return 1; };

struct baz_ 
{ 
    double operator()(){ return 0; } 
} baz;

using ReturnTypeOfFoo = return_type_of_t<decltype(foo)>;
using ReturnTypeOfBar = return_type_of_t<decltype(bar)>;
using ReturnTypeOfBaz = return_type_of_t<decltype(baz)>;
0 голосов
/ 07 декабря 2018

Наиболее простым и лаконичным, вероятно, является:

template <typename R, typename... Args>
R return_type_of(R(*)(Args...));

using ReturnTypeOfFoo = decltype(return_type_of(foo));

Обратите внимание, что это не будет работать для функциональных объектов или указателей на функции-члены.Только функции, которые не перегружены или шаблоны, или noexcept.

Но это может быть расширено для поддержки всех этих случаев, если это необходимо, добавив дополнительные перегрузки return_type_of.

...