C++ 在std::函数中获取std::future的结果类型

C++ 在std::函数中获取std::future的结果类型,c++,c++17,future,template-meta-programming,C++,C++17,Future,Template Meta Programming,假设一个std:::future f的实例,我如何从中获取类型T,以进行元编程,如decltype(f)::result\u type? 如果这个std::future在std::function c中,如何获取类型 例如,std::function具有成员类型result\u type和first\u argument\u type(虽然已弃用),但我找不到与std::future类似的东西 我的最小化用例: #include <future> #include <funct

假设一个
std:::future f
的实例,我如何从中获取类型
T
,以进行元编程,如
decltype(f)::result\u type
? 如果这个
std::future
std::function c
中,如何获取类型

例如,
std::function
具有成员类型
result\u type
first\u argument\u type
(虽然已弃用),但我找不到与
std::future
类似的东西

我的最小化用例:

#include <future>
#include <functional>

#include <iostream>

template<typename T>
using callback_t = std::function<void(std::future<T>)>;

void foo (callback_t<int> callback) {
    std::packaged_task<int/*How to not write int but derive the type from callback*/()> task {
        [] () {return 42;}
    };

    task();
    callback(task.get_future());
}

int main()
{
    callback_t<int> c {[] (auto i) {
        std::cout << i.get() << "\n";
    }};
    foo (c);
}
#包括
#包括
#包括
模板
使用callback\u t=std::函数;
void foo(回调\u t回调){
std::打包的任务{
[](){return 42;}
};
任务();
回调(task.get_future());
}
int main()
{
回调函数{[](自动i){
std::cout以下内容:

template<class T> struct get_first_argument_type {};
template<class R, class Arg>
struct get_first_argument_type<std::function<R(Arg)>> {
    using argument_type = Arg;
};

template<typename T>
void foo(callback_t<T> callback) {
    using the_future = typename get_first_argument_type<callback_t<T>>::argument_type;
    // https://stackoverflow.com/questions/26435084/how-to-get-the-return-type-of-a-member-function-from-within-a-class
    using your_type = typename std::result_of<decltype(&the_future::get)(the_future)>::type;
    static_assert(std::is_same<your_type, int>::value, "");
}
template struct get_first_argument_type{};
模板
结构获取第一个参数类型{
使用参数_type=Arg;
};
模板
void foo(回调\u t回调){
使用\u future=typename get\u first\u argument\u type::argument\u type;
// https://stackoverflow.com/questions/26435084/how-to-get-the-return-type-of-a-member-function-from-within-a-class
使用您的类型=typename std::result\u of::type;
静态断言(std::is_same::value,“”);
}
有效。

以下各项:

template<class T> struct get_first_argument_type {};
template<class R, class Arg>
struct get_first_argument_type<std::function<R(Arg)>> {
    using argument_type = Arg;
};

template<typename T>
void foo(callback_t<T> callback) {
    using the_future = typename get_first_argument_type<callback_t<T>>::argument_type;
    // https://stackoverflow.com/questions/26435084/how-to-get-the-return-type-of-a-member-function-from-within-a-class
    using your_type = typename std::result_of<decltype(&the_future::get)(the_future)>::type;
    static_assert(std::is_same<your_type, int>::value, "");
}
template struct get_first_argument_type{};
模板
结构获取第一个参数类型{
使用参数_type=Arg;
};
模板
void foo(回调\u t回调){
使用\u future=typename get\u first\u argument\u type::argument\u type;
// https://stackoverflow.com/questions/26435084/how-to-get-the-return-type-of-a-member-function-from-within-a-class
使用您的类型=typename std::result\u of::type;
静态断言(std::is_same::value,“”);
}
有效。

foo(回调)
中,不需要

如何不写int,而是从回调中派生类型

因为你知道
int
是参数,它就在那里

如果
foo
是一个模板,那么它也很简单

template <typename T>
void foo (callback_t<T> callback) {
    std::packaged_task<T()> task {
        [] () {return 42;}
    };

    task();
    callback(task.get_future());
}
模板
void foo(回调\u t回调){
std::打包的任务{
[](){return 42;}
};
任务();
回调(task.get_future());
}
如果你真的坚持提取它,你可以写一个特征

template <typename>
struct callback_arg;

template <typename T>
struct callback_arg<callback_t<T>> { using type = T; };

template <typename T>
using callback_arg_t = typename callback_arg<T>::type;
模板
结构回调参数;
模板
结构回调_arg{using type=T;};
模板
使用callback\u arg\u t=typename callback\u arg::type;
像这样使用它

using int_callback = std::function<void(std::future<int>)>;

void foo (int_callback callback) {
    std::packaged_task<callback_arg_t<int_callback>()> task {
        [] () {return 42;}
    };

    task();
    callback(task.get_future());
}
使用int\u callback=std::函数;
void foo(int_回调){
std::打包的任务{
[](){return 42;}
};
任务();
回调(task.get_future());
}
foo(回调)
中,不需要

如何不写int,而是从回调中派生类型

因为你知道
int
是参数,它就在那里

如果
foo
是一个模板,那么它也很简单

template <typename T>
void foo (callback_t<T> callback) {
    std::packaged_task<T()> task {
        [] () {return 42;}
    };

    task();
    callback(task.get_future());
}
模板
void foo(回调\u t回调){
std::打包的任务{
[](){return 42;}
};
任务();
回调(task.get_future());
}
如果你真的坚持提取它,你可以写一个特征

template <typename>
struct callback_arg;

template <typename T>
struct callback_arg<callback_t<T>> { using type = T; };

template <typename T>
using callback_arg_t = typename callback_arg<T>::type;
模板
结构回调参数;
模板
结构回调_arg{using type=T;};
模板
使用callback\u arg\u t=typename callback\u arg::type;
像这样使用它

using int_callback = std::function<void(std::future<int>)>;

void foo (int_callback callback) {
    std::packaged_task<callback_arg_t<int_callback>()> task {
        [] () {return 42;}
    };

    task();
    callback(task.get_future());
}
使用int\u callback=std::函数;
void foo(int_回调){
std::打包的任务{
[](){return 42;}
};
任务();
回调(task.get_future());
}

std::result_of(std::future::get())
@KamilCuk我不知道
std::result_of(decltype(回调)::第一个参数类型()
行不通您没有可以使用的成员类型。作为一种解决方法,
std::decay\u t
应该可以工作。我忘了在上面的文本中提到,另外,future是
std::function
函数中的一个参数
std::result\u of(std::future::get())
?@KamilCuk我不知道
std::result\u of(decltype(callback)::首先,参数类型())
不起作用。到目前为止,没有可以使用的成员类型。作为一种解决方法,
std::decay\t
应该起作用。我忘了在文本上方的文本中提到,另外,future是
std::function
中的一个参数,谢谢你,但我需要
foo
非模板化。(由于实现/编译障碍的解耦`然后不模板化它?删除
teamplte
,并用
int
替换
T
…但这当然很好,因为我一模板化foo,我就需要你的解决方案,而在非模板化foo中,我可以只写
int
,但我试图避免这种情况。谢谢你到目前为止,我还需要
foo
非模板化。(由于实现/编译障碍的解耦`然后不模板化它?删除
teamplte
,并用
int
替换
T
…但这当然很好,因为一旦我模板化了foo,我就需要你的解决方案,而在非模板化的foo中,我可以只写
int
,但我试图避免这种情况例如,如果我把
int
改为
long
,我只需要在一个地方把它改一下。有一个需要:DRY,例如,如果我把
int
改为
long
,我只需要在一个地方把它改一下。