【问题标题】:Get function return type in template获取模板中的函数返回类型
【发布时间】:2016-12-23 12:27:59
【问题描述】:

如何获取传递给模板的任何函数的返回类型?
我不知道如何在template<typename T>template<typename Result, typename Args...> 之间转换:

template<typename T>
void print_name(T f)
{
    static_assert(internal::is_function_pointer<T>::value
            || std::is_member_function_pointer<T>::value,
            "T must be function or member function pointer.");
    typename decltype(f(...)) Result; // ???
    typename std::result_of<T>()::type Result; // ???
    printf("%s\n", typeid(Result).name());
}

void f_void() {}
int f_int(int x) { return 0; }
float f_float(int x, int y) { return 0.f; }
struct X { int f(int x, float y) { return 0; } };

int main()
{
    print_name(f_void);
    print_name(f_int);
    print_name(f_float);
    print_name(&X::f);
    return 0;
}

如何在函数print_name 中输入Result

【问题讨论】:

  • 如果您要达到的目的是将结果放入变量中而不事先知道其类型,那么简单的auto a = f(x); 就足够了。
  • @JanNilsFerner 我怀疑他没有用于调用的参数。

标签: c++ templates c++14


【解决方案1】:

一种可能的解决方案是使用提取返回类型以及所有参数的函数声明。您甚至不必定义它。
它遵循一个最小的工作示例:

#include<typeinfo>
#include<cstdio>

template<typename R, typename... A>
R ret(R(*)(A...));

template<typename C, typename R, typename... A>
R ret(R(C::*)(A...));

template<typename T>
void print_name(T f)
{
    printf("%s\n", typeid(decltype(ret(f))).name());
}

void f_void() {}
int f_int(int x) { return 0; }
float f_float(int x, int y) { return 0.f; }
struct X { int f(int x, float y) { return 0; } };

int main()
{
    print_name(f_void);
    print_name(f_int);
    print_name(f_float);
    print_name(&X::f);
    return 0;
}

如您所见,为ret 提供的声明与提交的函数或成员函数具有相同的返回类型。
decltype 完成其余的工作。

【讨论】:

  • 这是 SFINAE 吗?
  • @Thomas 我会说重载。
  • 标准库中没有任何东西可以做 ret 的工作吗?
  • @einpoklum 这取决于标准的修订。在我写这篇文章的时候,我很想说no
  • @BenJones 捕获成员函数。另一个版本只接受免费功能。
【解决方案2】:

as of C++ 20, the answer is

std::invoke_result_t<T>

【讨论】:

  • 链接参考说这是在 C++17 中引入的,C++20 中是否有相关变化?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
相关资源
最近更新 更多