替换std :: function以将函数作为参数传递(回调等)

时间:2016-08-22 19:16:23

标签: c++ c++11

我在使用C ++ 11进行实验时偶然发现了这一点。我发现这是一个明显的解决方案,但我还没有能够在野外找到任何其他的例子,所以我担心我会缺少一些东西。

我所指的做法(在" addAsync"功能中):

#include <thread>
#include <future>
#include <iostream>
#include <chrono>

int addTwoNumbers(int a, int b) {
    std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;

    return a + b;
}

void printNum(std::future<int> future) {
    std::cout << future.get() << std::endl;
}

void addAsync(int a, int b, auto callback(std::future<int>) -> void) { //<- the notation in question
    auto res = std::async(std::launch::async, addTwoNumbers, a, b);

    if (callback) //super straightforward nullptr handling
        return callback(std::move(res));
}

int main(int argc, char** argv) {
    addAsync(10, 10, [](std::future<int> number) { //lambda functions work great
        addAsync(number.get(), 20, [](std::future<int> number) {
            addAsync(893, 4387, printNum); //as do standard functions
            addAsync(2342, 342, nullptr); //executes, sans callback

            std::cout << number.get() << std::endl;
        });
    });

    std::cout << "main thread: " << std::this_thread::get_id() << std::endl;

    return 0;
}

它被认为是不好的做法,还是不可移植(我只在MSVC ++ 2015中尝试过)?另外,编译器如何处理这个问题;通过转换为std :: function?

我希望在我的项目中继续使用它,因为它显然在&#34;签名&#34;中声明了所需的参数类型和返回类型,接受了nullptr的可选性,并且似乎&#34;只是工作&#34; (我知道这些是C ++中着名的最后一句话)。

3 个答案:

答案 0 :(得分:17)

auto callback(std::future<int>) -> void是名为void(std::future<int>)的{​​{1}}类型实体的声明。当列为参数时,编译器会将其调整为类型callback的指针。

你的lambda是无状态的,因此可以隐式转换为函数指针。

添加非平凡的捕获后,您的代码将停止编译:

void(*)(std::future<int>)

...

现在,忽略您的问题内容并查看标题......

[argc](std::future<int> number) { std::cout << argc << '\n'; 的成本适中,因为它是值类型,而不是视图类型。作为一个值类型,它实际上复制了它的参数。

你可以通过将调用对象包装在std::function中来解决这个问题,但如果你想说“我不会让这个函数对象比这个调用更长时间”,你可以写一个{{1键入如下:

std::ref

live example

这也是有用的,因为它是一种比function_view更简单的类型擦除,所以重复它可能具有教育意义。

答案 1 :(得分:13)

您正在使用原始指针来运行。

std::function不同,这不适用于捕获{或std::bind的结果的lambda,或使用实现operator()的通用类类型。

答案 2 :(得分:1)

用于将函数作为参数传递的std :: function的替代方法&#34;

一种替代方案是函数指针(包括成员函数指针)。但是std::function更好(IMO)。