简体   繁体   English

C ++ 17结合了std :: async和std :: invoke

[英]C++17 combine std::async and std::invoke

I am trying to call std::invoke from inside a std::async call but for some reason the compiler don't like it. 我正在尝试从std :: async调用内部调用std :: invoke,但是由于某种原因,编译器不喜欢它。

Note : I know I could use a lambda, but I would like to make it work without it 注意:我知道我可以使用lambda,但是我想在没有它的情况下使它起作用

Here is my example. 这是我的例子。

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

Thank you for your help. 谢谢您的帮助。

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

std::invoke is a template function. std::invoke是模板函数。 Therefore simply naming the template name is ambiguous - which of the infinite set of std::invoke<F, Args...> do you mean? 因此,简单地命名模板名称是模棱两可的-您是说std::invoke<F, Args...>的无限集合中的哪一个?

You'll need to provide an 'invoker' concrete object. 您需要提供一个“调用者”具体对象。

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

Same with the template function runTerminateOnException. 与模板函数runTerminateOnException相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM