C 17结合了std :: async和std :: Invoke

C++17 combine std::async and std::invoke

本文关键字:std Invoke async 结合了      更新时间:2023-10-16

我试图从std :: async调用std ::调用,但是由于某种原因,编译器不喜欢它。

注意:我知道我可以使用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;
}

谢谢您的帮助。

http://coliru.stacked-crooked.com/a/51f8c8c80b0a05fa0e

std::invoke是模板函数。因此,简单地命名模板名称是模棱两可的 - 您的意思是哪一组无限的std::invoke<F, Args...>

您需要提供"调用"混凝土对象。

eg:

#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;
}

与模板函数runterminateOnexception相同。