我可以得到一个函数从签名的返回类型?(Can I get the Return Type of a

2019-10-30 01:29发布

所以,我有一吨的类似于以下功能:

template <typename T>
bool Zero(const T, const T, const T);
template <typename T>
T One(const T, const T, const T, bool);
template <typename T>
T Three(const T, const T, const T, const T, const T, const T);

对于这些功能,我有一个使用这些功能,所以它看起来是这样的返回类型的包装:

template <typename T>
decltype(Zero<decltype(declval<T>().x)>(decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()))) ZeroWrapper(const T);
template <typename T>
decltype(One<decltype(declval<T>().x)>(decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), bool())) OneWrapper(const T);
template <typename T>
decltype(Three<decltype(declval<T>().x)>(decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()), decltype(declval<decltype(declval<T>().x)>()))) ThreeWrapper(const T);

正如你可以看到所有这些decltype(declval<T>().x)的获得令人作呕难以阅读。 我可以一个模板using或者是有一些标准的功能,这将让我来提取一个函数指针的返回类型,而没有经过参数类型decltyperesult_of ? 因此,像这样:

template <typename T>
foo_t<Zero<decltype(declval<T>().x)>> ZeroWrapper(const T);
template <typename T>
foo_t<One<decltype(declval<T>().x)>> OneWrapper(const T);
template <typename T>
foo_t<Three<decltype(declval<T>().x)>> ThreeWrapper(const T);

Answer 1:

我可以一个模板使用或者是有一些标准的功能,这将让我来提取一个函数指针的返回类型,而没有经过参数类型decltyperesult_of

是!

#include <tuple>
#include <functional>

template<class T>
struct callable_trait
{};

template<class R, class... Args>
struct callable_trait<std::function<R(Args...)>>
{
    using return_type    = R;
    using argument_types = std::tuple<Args...>;
};

template<auto callable>
using return_type = typename callable_trait<decltype(std::function{callable})>::return_type;

return_type<some_callable>是由返回的类型some_callable当与适当的参数调用。 此使用std::function以对于每个可能的类型的可调用的(自由功能,函数指针,成员函数,函子对象)提供一个专门化。 这是在这个StackOverflow的答案解释 。


你的情况,你可以使用它像这样:

template <typename T>
bool Zero(const T, const T, const T);
template <typename T>
T One(const T, const T, const T, bool);
template <typename T>
T Three(const T, const T, const T, const T, const T, const T);

template <typename T>
return_type<Zero<T>>  ZeroWrapper(const T);
template <typename T>
return_type<One<T>>   OneWrapper(const T);
template <typename T>
return_type<Three<T>> ThreeWrapper(const T);

完整的示例



Answer 2:

在C ++ 17的function对象被赋予了一个推导指南这使得它能够确定它是从传递给构造的参数类型。 因此,例如,给定函数int foo()在C ++ 11 ,我们不得不这样做:

function<int()> bar(foo);

在C ++ 17 barfunction<int()>类型将被如果我们简单地导出:

function bar(foo);

因此,我们可以用扣除指南填充临时function 签字; 从而使用functionresult_type找到你的助手funcitons的结果:

template <typename T>
typename decltype(function(Zero<decltype(declval<T>().x)>))::return_type ZeroWrapper(const T);
template <typename T>
typename decltype(function(One<decltype(declval<T>().x)>))::return_type OneWrapper(const T);
template <typename T>
typename decltype(function(Three<decltype(declval<T>().x)>))::return_type ThreeWrapper(const T);

活生生的例子



文章来源: Can I get the Return Type of a Function From a Signature?