C++ C++;17组合std::async和std::invoke

C++ C++;17组合std::async和std::invoke,c++,c++17,C++,C++17,我试图从std::async调用内部调用std::invoke,但由于某些原因,编译器不喜欢它 注: 我知道我可以用lambda,但我想不用它也能用 这是我的例子 #include <iostream> #include <future> #include <string> #include <functional> #include <type_traits> #include <unistd.h> template &

我试图从std::async调用内部调用std::invoke,但由于某些原因,编译器不喜欢它

注: 我知道我可以用lambda,但我想不用它也能用

这是我的例子

#include <iostream>
#include <future>
#include <string>
#include <functional>
#include <type_traits>
#include <unistd.h>

template <class Fn, class... Args>
inline std::result_of_t<Fn&&(Args&&...)> runTerminateOnException(Fn&& fn, Args&&... args) {
    try {
        return std::invoke(std::forward<Fn>(fn), std::forward<Args>(args)...);
    } catch (...) {
        std::terminate();
    }
}

struct A {
        static void g(double x, std::string *s) {
            std::cout << "g() : x = " << x << ", *s = " << *s << std::endl;
            usleep(100);
        }

        static void f(double x, std::string *s) {
            std::invoke(g, x, s); // Working
            auto future1 = std::async(std::launch::async, g, x, s); // Working
            auto future2 = std::async(std::launch::async, std::invoke, g, x, s); // Not working
            auto future3 = std::async(std::launch::async, runTerminateOnException, g, x, s); // Not working
        }
};

int main() {
    std::string s = "Hello";
    A::f(10., &s);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
模板
inline std::runTerminateOnException的结果(Fn&&Fn,Args&&Args){
试一试{

return std::invoke(std::forward(fn),std::forward

std::invoke
是一个模板函数。因此简单地命名模板名称是不明确的-你指的是无限组
std::invoke
中的哪一个

您需要提供一个“invoker”具体对象

例如:

#包括
#包括
#包括
#包括
#包括
#包括
模板
inline std::runTerminateOnException的结果(Fn&&Fn,Args&&Args){
试一试{
返回std::invoke(std::forward(fn)、std::forward(args)…);
}捕获(…){
std::terminate();
}
}
结构调用程序
{
模板
decltype(自动)运算符()(F&&F,Args&&…Args)常量{
返回std::invoke(f,std::forward(args)…);
}
};
结构A{
静态空g(双x,标准::字符串*s){

std::你可能会把
std::invoke
std::bind
@InfiniteLop混淆吗?是的,带有自动参数的lambda只是不同服装中的一个调用程序。你为什么在“参数”上使用std::forward(),而不是在“f”上使用在调用程序?@InfiniteLop中,仅要求函数对象引用为r值以调用它是不寻常的。以下两个调用需要有意义的区别:
f(arg)
std::move(f)(arg)
。我想我们大多数人都会同意,这会让函数对象的用户感到惊讶。
auto
应该是
decltype(auto)
on
operator()
#include <iostream>
#include <future>
#include <string>
#include <functional>
#include <type_traits>
#include <unistd.h>

template <class Fn, class... Args>
inline std::result_of_t<Fn&&(Args&&...)> runTerminateOnException(Fn&& fn, Args&&... args) {
    try {
        return std::invoke(std::forward<Fn>(fn), std::forward<Args>(args)...);
    } catch (...) {
        std::terminate();
    }
}

struct invoker
{
    template<class F, class...Args>
    decltype(auto) operator()(F&& f, Args&&...args) const {
        return std::invoke(f, std::forward<Args>(args)...);
    }
};

struct A {
        static void g(double x, std::string *s) {
            std::cout << "g() : x = " << x << ", *s = " << *s << std::endl;
            usleep(100);
        }

        static void f(double x, std::string *s) {
            std::invoke(g, x, s); // Working
            auto future1 = std::async(std::launch::async, g, x, s); // Working
            auto future2 = std::async(std::launch::async, invoker(), g, x, s); // Working now
//          auto future3 = std::async(std::launch::async, runTerminateOnException, g, x, s); // Not working
        }
};

int main() {
    std::string s = "Hello";
    A::f(10., &s);
    return 0;
}