如何检索要在模板中使用的函数的返回类型?

时间:2016-12-31 10:46:15

标签: c++

我有一个名为x的函数,它返回一个已知值并具有已知参数:

int x(int y);

我还有其他地方,我想创建一个容器来包含此函数的n次调用。然后我想多次执行它。

问题是,我不想依赖它是int返回类型。我需要在编译时推断出返回类型。类似的东西:

std::vector<result_of<x(int)>::type> results;

但我不想指定参数值,因为它们是静态的。

4 个答案:

答案 0 :(得分:6)

您可以创建自己的特征,例如:

template <typename F> struct my_result_of;

template <typename F> struct my_result_of<F*> : my_result_of<F> {};

template <typename Ret, typename ... Ts>
struct my_result_of<Ret(Ts...)>
{
    using type = Ret;
};

template <typename F> using my_result_of_t = typename my_result_of<F>::type;

并使用它(假设没有x的重载):

std::vector<my_result_of_t<decltype(x)>::type> results;

答案 1 :(得分:5)

你很亲密。假设T是调用函数的模板参数:

std::vector<decltype(x(std::declval<T>()))> results;

答案 2 :(得分:2)

您可以滥用std::function::result_type

int x(int y);
static_assert(std::is_same_v<int,std::function<decltype(x)>::result_type>);

当然,这仅在x真正起作用时才有效。如果x是任意函数对象,则其结果类型可能取决于其参数类型,在这种情况下,如果不指定参数,则无法知道其结果类型。

答案 3 :(得分:2)

我认为您可以使用最新的标准版本,因为您没有指定它 这是一个最小的工作示例:

#include<vector>
#include<functional>
#include<utility>

template<std::size_t... I, typename F, typename... A>
auto gen(std::index_sequence<I...>, F &&f, A... args) {
    return std::vector<decltype(std::forward<F>(f)(args...))>{
        (I, std::forward<F>(f)(args...))...
    };
}

template<std::size_t N, typename F, typename... A>
auto gen(F &&f, A... args) {
    return gen(std::make_index_sequence<N>{}, std::forward<F>(f), args...);
}

int f(int, char) { return 0; }

int main() {
    auto vec = gen<10>(&f, 0, 'c');
}

您的功能的返回类型很容易推断:

decltype(std::forward<F>(f)(args...))
  

我想创建一个容器来包含n个这个函数的调用。然后我想多次执行它。

为此,我使用std::index_sequence创建了一个大小合适的参数包 然后矢量本身初始化如下:

(I, std::forward<F>(f)(args...))...

基本思想是利用逗号运算符解包上面提到的参数包并执行N次函数。 f的调用返回的值用于填充向量。

请注意,args并未完美转发至f 如果在第一次执行期间消耗了可移动对象,则可能会导致问题。