简体   繁体   English

广义 std::function (std::any 用于可调用对象)

[英]Generalised std::function (std::any for callable objects)

How can I create a variable of generalised std::function type that can take any callable objects?如何创建可以采用任何可调用对象的通用std::function类型的变量? I can't use variadic templates because it'll create a family of different types, while I need a single type, so that I can take different [&] lambdas to a same array.我不能使用可变参数模板,因为它会创建一个不同类型的系列,而我需要一个类型,这样我就可以将不同的[&] lambdas 带到同一个数组中。

I did it with functors (example below) that produce std::function<void()> , but for this I have to create a functor for every set of arguments that my functions use.我使用产生std::function<void()>的仿函数(下面的示例)来完成它,但为此我必须为我的函数使用的每一组 arguments 创建一个仿函数。 Now I want to use lambdas to bind arguments, but their type is tricky and I can't get different lambdas to the same array.现在我想使用 lambdas 来绑定 arguments,但它们的类型很棘手,我无法将不同的 lambdas 用于同一个数组。

I understand that this will be very unsafe.我知道这将是非常不安全的。

#include <iostream>
#include <vector>
#include <string>

using ChoiceArray = std::vector<std::function<void()>>;
int GetInt(int restriction);

class MenuFunctor {
private:
    std::string output;
    ChoiceArray arrayOfFunctions;
public:
    MenuFunctor(std::string n_output, ChoiceArray n_arrayOfFunctions)
        : output(n_output), arrayOfFunctions(n_arrayOfFunctions)
    { }
    void operator()() const {
        int selection;
        std::cout << output;
        selection = GetInt(int(arrayOfFunctions.size()));
        arrayOfFunctions[selection]();
    }
};

class OperationFunctor {
private:
    std::function<void(std::vector<std::string>*)> func;
    std::vector<std::string>* container;
public:
    OperationFunctor(std::function<void(std::vector<std::string>*)> n_func, std::vector<std::string>* n_container)
        : func(n_func), container(n_container)
    { }
    void operator()() const {
        func(container);
    }
};

void Func1(std::vector<std::string>* container);
void Func2(std::vector<std::string>* container);
void Func3(std::vector<std::string>* container);

int main() {
    std::vector<std::string> container;
    std::vector<std::string>* containerAddress = &container;
    OperationFunctor f1(Func1, containerAddress);
    OperationFunctor f2(Func2, containerAddress);
    OperationFunctor f3(Func3, containerAddress);
    ChoiceArray Array = {f1, f2, f3};
    MenuFunctor Start("input 0-2\n", Array);
    Start(); // Works
    return 0;
}

Also, I tried to take std::vector<std::string> container for Func1 - Func3 by reference, but it didn't work, so I went with pointers.另外,我尝试通过引用为Func1 - Func3获取std::vector<std::string> container ,但它不起作用,所以我使用了指针。 It has something to do with perfect forwarding?它与完美转发有关吗?

Just stuff lambdas into std::function<void()> .只需将 lambda 填充到std::function<void()>中。

using OperationFunctor = std::function<void()>;
using ChoiceArray = std::vector<OperationFunctor>;

int GetInt(int restriction);

class MenuFunctor {
private:
    std::string output;
    ChoiceArray arrayOfFunctions;
public:
    MenuFunctor(std::string n_output, ChoiceArray n_arrayOfFunctions)
        : output(n_output), arrayOfFunctions(n_arrayOfFunctions)
    { }
    void operator()() const {
        int selection;
        std::cout << output;
        selection = GetInt(int(arrayOfFunctions.size()));
        arrayOfFunctions[selection]();
    }
};

void Func1(std::vector<std::string>* container);
void Func2(std::vector<std::string>* container);
void Func3(std::vector<std::string>* container);

int main() {
    std::vector<std::string> container;
    std::vector<std::string>* containerAddress = &container;

    OperationFunctor f1([containerAddress]{ Func1(containerAddress) });
    OperationFunctor f2([containerAddress]{ Func2(containerAddress) });
    OperationFunctor f3([containerAddress]{ Func3(containerAddress) });
    ChoiceArray Array = {f1, f2, f3};
    MenuFunctor Start("input 0-2\n", Array);
    Start(); // Works
    return 0;
}

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

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