标签: std-function

在 std::function 中捕获 lambda 会产生额外的副本

我正在尝试编写一些代码,通过将函数调用及其参数存储在 lambda/std::function 中,允许我稍后调用函数。理想情况下,参数只会被复制一次(并以其他方式移动),但我可以实现的最小副本数似乎是 2。

//==============================================================================
// INCLUDES
//==============================================================================

#include <iostream>
#include <functional>
#include <memory>

//==============================================================================
// VARIABLES
//==============================================================================

static std::unique_ptr<std::function<void()>> queueFunction;

//==============================================================================
// CLASSES
//==============================================================================

class Test {
public:
    Test(int a, int b = 20, int c = 30) : _a(a), _b(b), _c(c) {
        std::cout << "Test: Constructor" << std::endl;
    }
    
    ~Test() {
        std::cout << "Test: Destructor" << std::endl;
    }
    
    Test(const Test& other) :
        _a(other._a)
    {
        std::cout << "Test: Copy Constructor" << std::endl;
    }
    
    Test(Test&& other) :
        _a(std::move(other._a))
    {
        std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ lambda std-function

2
推荐指数
1
解决办法
448
查看次数

为什么 `function&lt;void (string)&gt;` 和 `function&lt;string (string)&gt;` 参数类型有时对于重载来说不明确?

跟进我的问题c++ - 使用中间类型时隐式转换如何工作?,从中我了解了1 隐式转换 max的规则,我试图了解涉及函数参数的更高级用例。

假设我有一个函数,它接受另一个函数作为参数。该函数参数可以返回某些内容,也可以不返回任何内容(void)。因此,我想重载函数定义,在一种情况下接受非 void 函数参数,在另一种情况下接受 void 函数参数。

using VoidType = void (string);
using NonVoidType = string (string);

string call(VoidType *fn, string arg) {
    cout << "[using void function]" << endl;
    fn(arg);
    return arg;
}

string call(NonVoidType *fn, string arg) {
    cout << "[using non void function]" << endl;
    return fn(arg);
}
Run Code Online (Sandbox Code Playgroud)

调用函数时,给定参数具有已知类型,因此重载选择应该很简单,如下所示:

void printVoid(string message) {
    cout << message << endl;
}

string printNonVoid(string message) {
    cout << message << endl;
    return message;
} …
Run Code Online (Sandbox Code Playgroud)

c++ overloading ambiguous implicit-conversion std-function

2
推荐指数
1
解决办法
402
查看次数

如何重置 std::function?

std::function可以为空,并且可以转换为bool测试它是否有目标。但是,在给它赋值后如何将其设置为 null 呢?

int main()
{
    std::function<void()> f = []() { return 4; };
    // how to reset to null, to it's initial state when default constructed.
}
Run Code Online (Sandbox Code Playgroud)

c++ std-function

2
推荐指数
2
解决办法
2061
查看次数

如何避免使用std :: bind()临时对象进行显式转换?

std :: bind的返回类型是(有意)未指定的.它可以存储在std :: function中.

下面的示例程序显示了如何将std :: bind()返回的临时对象显式转换为std :: function以调用fn1().

如果std :: bind的返回类型是可知的,我可以重载Callback构造函数并且不再需要显式地转换std :: bind临时对象.

有没有办法避免显式演员?

// g++ -std=c++11 test.cxx
#include <functional>

using std::placeholders::_1;

class A
{
    public:
        void funcA (int x) { }
};

class Callback
{
    public:
        Callback () = default;
        Callback (std::function<void(int)> f) { }
        // Wish we knew the return type of std::bind()
        // Callback (return_type_of_std_bind f) { }
};

void fn0 (std::function<void(int)> f) { }
void fn1 (Callback cb) { }

int main …
Run Code Online (Sandbox Code Playgroud)

c++ stl stdbind c++11 std-function

1
推荐指数
1
解决办法
1062
查看次数

如何使模板函数成为另一个模板函数的参数?

我有一个包含各种算法的类:

class Algorithm{

Algorithm()=delete;

public:
    template <typename IntegerType> 
    static IntegerType One(IntegerType a, IntegerType b);

    template <typename IntegerType> 
    static IntegerType Two(IntegerType a, IntegerType b);

    template <typename IntegerType> 
    static IntegerType Three(IntegerType a, IntegerType b);

    // ...
};
Run Code Online (Sandbox Code Playgroud)

它们可以通过以下方式调用:

int main(){

    Algorithm::One(35,68);
    Algorithm::Two(2344,65);
    //...
}
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个函数,它将采用任何"算法"函数,并在调用该函数之前和之后执行相同的步骤.
这是我有的:

template <typename IntegerType>
void Run_Algorithm(std::function<IntegerType(IntegerType,IntegerType)>fun, IntegerType a, IntegerType b){
    //... stuff ...
    fun(a,b);
    //... stuff ...
    return;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试像这样调用函数时:

Run_Algorithm(Algorithm::One,1,1);
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

cannot resolve overloaded function ‘One’ based on conversion to type ‘std::function<int(int, int)>’
Run Code Online (Sandbox Code Playgroud)

如何设置通用例程,将所需算法作为参数?

编辑:
此解决方案 …

c++ parameters templates c++11 std-function

1
推荐指数
1
解决办法
134
查看次数

C++类型擦除,使用std :: function捕获单个类的多个方法

请考虑以下代码,其中std::function使用三次来捕获一个类的方法:

struct some_expensive_to_copy_class
{
    void foo1(int) const { std::cout<<"foo1"<<std::endl; }
    void foo2(int) const { std::cout<<"foo2"<<std::endl; }
    void foo3(int) const { std::cout<<"foo3"<<std::endl; }
};

struct my_class
{
    template<typename C>
    auto getFunctions(C const& c)
    {
         f1 = [c](int i) { return c.foo1(i);};
         f2 = [c](int i) { return c.foo2(i);};
         f3 = [c](int i) { return c.foo3(i);};
    }

    std::function<void(int)> f1;
    std::function<void(int)> f2;
    std::function<void(int)> f3;
};
Run Code Online (Sandbox Code Playgroud)

然而,这将执行该类的三个副本some_expensive_to_copy_class,这是低效的,因为人们可能已经猜到了这个名称.

是否有一个解决方法,只有一个副本?

为了强调它,我对这里使用的方法感兴趣std::function,而不是void-pointers,也没有相应的基于继承的实现.

c++ type-erasure c++11 std-function

1
推荐指数
1
解决办法
86
查看次数

设置为std :: function的目标将丢失

我为std :: function设置的目标丢失了,我不知道为什么我可能忽略了这个程序中的一些小错误.有人可以帮忙吗

class Test将lambda注册到单例类,但是当尝试调用回调时,std :: function中的目标集将丢失.

#include <iostream>
#include <functional>

using namespace std;

class callback_store final
{

    using callback_func_type = std::function<void()>;

    public:
    static callback_store instance()
    {
        static callback_store instance;
        return instance;
    }

    void register_callback(callback_func_type func)
    {
        std::cout << "register_callback() <<<" << std::endl;
        m_func = func;

        // I am able to call the targets from here.
        std::cout << "register_callback() func() " <<  std::endl;
        func();
        std::cout << "register_callback() m_func() "  << std::endl;
        m_func();

        // some stats
        std::cout << "register_callback() :: " …
Run Code Online (Sandbox Code Playgroud)

c++ lambda callable c++11 std-function

1
推荐指数
1
解决办法
221
查看次数

将lambda存储为std :: function时出现分段错误

以下代码给出了分段错误.调试之后,我发现问题可以通过将lambda声明为auto而不是Function来解决.为什么会这样?

#include <functional>
#include <iostream>
#include <vector>

typedef std::vector<double> Vec;
typedef std::function<const Vec&(Vec)> Function;


int main()
{
     //Function func = [](const Vec& a)->Vec /*this give me segfault*/
     auto func = [](const Vec& a)->Vec /*this work just fine??*/
         {
              Vec b(2);
              b[0] = a[0] + a[1];
              b[1] = a[0] - a[0];
              return b;
         };
     Vec b = func(Vec{1,2});
     std::cout << b[0] << " " << b[1] << "\n";
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我可以将它声明为Function,那将是很好的,因为我想将这个lambda表达式传递给其他类.

当func声明为Function时,我所遇到的错误是:

程序接收信号SIGSEGV,分段故障.0x0000000000401896在std :: vector> :: size(this = 0x0)/usr/include/c++/5/bits/stl_vector.h:655 655 …

c++ lambda std-function

1
推荐指数
1
解决办法
959
查看次数

何时捕获捕获变量?

我正在进行std::vector回调std::function,而我在理解捕获时遇到了一些麻烦.当我尝试使用它们时,它们似乎超出了范围,如果我通过引用捕获它们.如果我按价值捕获,一切正常.

使用这些回调函数的代码需要一定的签名,所以假设我无法修改使用它们的代码,我需要坚持使用捕获变量而不是将事物作为函数参数传递.

localVar捕获?是在定义lambda还是调用lambda时?答案是否会根据我是按值还是参考来捕获?

这是我想要了解的一个小例子:

#include <iostream>
#include <functional>
#include <vector>

int main(int argc, char **argv)
{

    int n(5);

    // make a vector of lambda functions
    std::vector<std::function<const int(void)> > fs;
    for(size_t i = 0; i < n; ++i){
        int localVar = i;
        auto my_lambda = [&localVar]()->int // change &localVar to localVar and it works
        {
            return localVar+100;
        };
        fs.push_back(my_lambda);
    }

    // use the vector of lambda functions
    for(size_t i = 0; i < n; …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11 std-function

1
推荐指数
1
解决办法
91
查看次数

如何使用相同的模板语法创建一个function_list &lt;&gt;类来保存std :: function &lt;&gt; s的向量?

我希望有一个function_list <>模板类,其中包含std :: function <>值的向量。关键是我想用声明单个std :: function <>的相同形式声明列表。例如

function_list<void()> functions; // list of std::functions that take and return void
Run Code Online (Sandbox Code Playgroud)

下面是我尝试实现的方法。我尝试遵循标准库的函数头文件中std :: function <>模板所使用的相同语法。

#include <functional>
#include <vector>
#include <iostream>

template<class _R, class... _Args>
class function_list<_R(_Args...)>
{
public:
  std::vector<std::function<_R(_Args...)>> functions;
  function_list& operator+=(std::function<_R(_Args...)> f) { functions.push_back(f); return *this; }
  void call_all(_Args... args) { for (auto& f : functions) { f(args...); } }
};

int main()
{
  function_list<void()> fl;
  fl += []() { std::cout << "Hello, World!" << std::endl; };
  fl …
Run Code Online (Sandbox Code Playgroud)

c++ templates delegates c++11 std-function

1
推荐指数
1
解决办法
43
查看次数