标签: std-function

使用shared_ptr和weak_ptr管理std :: function的生存期是否安全?

我围绕boost :: asio :: io_service创建了一个包装器,以处理OpenGL应用程序的GUI线程上的异步任务。

任务可能是从其他线程创建的,因此boost::asio看来是理想的选择,这意味着我不需要编写带有关联互斥锁和锁定的任务队列。我想将每个帧上完成的工作保持在可接受的阈值(例如5毫秒)以下,因此我要打电话poll_one直到超出所需的预算为止,而不是打电话run。据我所知,这要求我reset在发布新任务时都打电话给我,这似乎效果很好。

由于很短,所以这里是整件事,无#include:

typedef std::function<void(void)> VoidFunc;
typedef std::shared_ptr<class UiTaskQueue> UiTaskQueueRef;

class UiTaskQueue {

public:

    static UiTaskQueueRef create()
    {
        return UiTaskQueueRef( new UiTaskQueue() );
    }

    ~UiTaskQueue() {} 

    // normally just hand off the results of std/boost::bind to this function:
    void pushTask( VoidFunc f )
    {
        mService.post( f );
        mService.reset();
    }

    // called from UI thread; defaults to ~5ms budget (but always does one call)        
    void update( const …
Run Code Online (Sandbox Code Playgroud)

c++ boost-thread shared-ptr boost-asio std-function

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

std :: function和Signal/Slot系统

我试图在没有提升的情况下用C++创建一个简单的信号/插槽系统,但是当我尝试将它与参数一起使用时,我遇到了一些问题,这是我的代码:

我的信号类:

template <typename T> 
class Signal
{
private:
    typedef std::function<T> Slot;

public:
    Signal();

    void connect( Slot slot );
    void emit( T data );
    void emit();

private:    
    std::vector<Slot> slots;    
};
Run Code Online (Sandbox Code Playgroud)

我的测试课:

class Object
{
public:
    Object();
    void sayHello(  int i  );
};
Run Code Online (Sandbox Code Playgroud)

所以,我像这样使用我的班级:

Signal<void(int)> signal;
signal.connect( std::bind( &Object::sayHello, player, std::placeholders::_1 ) );
signal.emit( 0 );
Run Code Online (Sandbox Code Playgroud)

我在Signal.cpp中收到警告: 候选函数不可行:第一个参数没有从'void(*)(int)'到'int'的已知转换;

在这段代码中:

template <typename T>
void Signal<T>::emit( T data )
{
    typename std::vector<Slot>::iterator i;
    Slot t;

    for( i = this->slots.begin(); i != this->slots.end(); i++ …
Run Code Online (Sandbox Code Playgroud)

c++ signals signals-slots c++11 std-function

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

返回返回std :: function的函数的类型

我有一个函数应该返回与该函数相同类型的std ::函数.基本上我想要这样的东西:

using RetType = std::function<RetType(void)>;
Run Code Online (Sandbox Code Playgroud)

这显然不会编译.如何正确声明返回类型?

c++ templates c++11 std-function

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

用任何签名创建一个"do-nothing"`std :: function`?

我想创建一个std::function带有任意签名的简单无操作对象.为此,我创建了两个函数:

template <typename RESULT, typename... ArgsProto>
  std::function<RESULT(ArgsProto...)> GetFuncNoOp()
  {
    // The "default-initialize-and-return" lambda
    return [](ArgsProto...)->RESULT { return {}; };
  }

template <typename... ArgsProto>
  std::function<void(ArgsProto...)> GetFuncNoOp()
  {
    // The "do-nothing" lambda
    return [](ArgsProto...)->void {};
  }
Run Code Online (Sandbox Code Playgroud)

这些中的每一个都运行得很好(显然第一个版本可能在RESULT对象中创建未初始化的数据成员,但实际上我认为这不会是一个大问题).但是第二个 - void返回版本是必要的,因为return {}; 永远不会返回void(这将是编译错误),并且它不能被写为第一个的模板特化,因为初始签名是可变参数.

所以我不得不在这两个函数之间进行选择,只实现一个,或给它们不同的名称.但我真正想要的是以std::function这样的方式轻松初始化对象:当被调用时,它们什么也不做,而不是抛出异常.这可能吗?

请注意,默认构造函数std::function不能做我想要的.

c++ lambda variadic-templates c++11 std-function

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

如何将成员函数作为参数?

我正在努力使用C++模板,函数和绑定.

假设我的班级A是这样的:

class A {
    void set_enabled_for_item(int item_index, bool enabled); 

    void set_name_for_item(int item_index, std::string name); 

    int item_count();
}
Run Code Online (Sandbox Code Playgroud)

我想像这样创建一个方法A:

    template <typename T>
    void set_for_all_items(T value, ??? func) {
        auto count = trackCount();
        for (auto i = 0; i < count; ++i) {
            func(i, value);
        }
    }
Run Code Online (Sandbox Code Playgroud)

所以我可以用参数中的A成员函数来调用它,就像这样(或类似的东西):

auto a = new A;
a->set_for_all_items("Foo Bar", &A::set_name_for_item);
Run Code Online (Sandbox Code Playgroud)

这三个???将是第二个参数的类型.由于我对std :: function,std :: bind和templates很新,我尝试了我已经知道的但是我总是遇到编译错误.

那怎么办呢?

c++ std-function

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

变体模板,类型演绎和std :: function

我正在尝试创建一个模板函数,可以通过任何类型和数量的参数传递一些其他函数并将其绑定到std::function.我成功地做到了这一点:

#include <iostream>
#include <functional>

int foo(int bar)
{
  std::cout << bar << std::endl;
  return bar;
}

template <typename Ret, typename... Args>
std::function<Ret (Args...)> func(std::function<Ret (Args...)> f)
{
  return f;
}

int main()
{
  //auto barp = func(foo); // compilation error
  auto bar  = func(std::function<void (int)>(foo));

  bar (0); // prints 0
}
Run Code Online (Sandbox Code Playgroud)

我想调用auto barp = func(foo);并推导出类型,但是这一行给出了以下编译错误:

error: no matching function for call to ‘func(void (&)(int))’
    auto barp = func(foo);
                        ^
note: candidate is:
note: template<class Ret, …
Run Code Online (Sandbox Code Playgroud)

c++ variadic-templates c++11 std-function

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

如何为lambda构造std :: function

我对std::function在给定的lambda中构造的方式感到有些困惑.这里std::function列出了构造函数.哪一个实际用于捕获一个lambda?是template< class F > function( F f );吗?看起来我无法std::function使用捕获非可复制构造对象的lambda构造.为什么这对lambda捕获是必要的?

// fu is an object of type std::future 
std::function f = [future=std::move(fu)]() {...}  // compile error

// foo is an object of type int
std::function f = [foo=std::move(foo)]() {...} // compile ok
Run Code Online (Sandbox Code Playgroud)

lambda c++11 std-function

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

将成员函数作为参数传递给其他成员函数(C++ 11 <function>)

假设我有一个包含三个成员函数的类,如下所示:

#include <iostream>
#include <functional>

class ClassName
{
  public:
    double add(double a, double b);
    double intermediate(double a, double b, std::function<double (double,double)> func);
    double combiner(double a, double b);
};

double ClassName::add(double a, double b)
{
  return a+b;
}

double ClassName::intermediate(double a, double b, std::function<double (double,double)> func)
{
  return func(a, b);
}

double ClassName::combiner(double a, double b)
{
  return intermediate(a, b, add);
}

int main()
{
  ClassName OBJ;
  std::cout << OBJ.combiner(12, 10);
}
Run Code Online (Sandbox Code Playgroud)

我想要做的是将成员函数"add"传递给成员函数"intermediate",然后由"combiner"调用.但是,我不认为我使用正确的语法,因为当我尝试编译它时,我收到一条错误,说"非标准语法;使用'&'创建指向成员的指针." 我不太确定会出现什么问题,因为如果这些函数不是类中的成员函数(只是命名空间中定义的常规函数​​),则此方法可以正常工作. 那么是否可以将成员函数传递给另一个成员函数?

c++ function member-functions std-function

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

是std :: function比自动存储lambda函数更重要

我听说费用std::function比auto处理lambda函数要重.有效的现代c ++ item5.我想要的是澄清为什么std::function使用更多内存而不是auto一些示例代码的机制.有人能帮帮我吗?

编辑

class Widget {
public:
  Widget(int i) : i_(i) {}
  bool operator<(const Widget& o) { return o.value() > i_; }
  int value() const { return i_; };
private:
  int i_;
  int dummy_[1024];
};

int main() {
  // performance difference between auto and std::function
  { 
    auto less1 = [](const auto& p1, const auto& p2) {
      return *p1 < *p2;
    };
    std::cout << "size of less1: " << sizeof(less1) << endl; …
Run Code Online (Sandbox Code Playgroud)

c++ lambda auto c++11 std-function

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

使用名称标记std :: function?

我正在研究一个解析器组合库,我真的很喜欢我的解析器只是一个可调用的对象:

typedef std::function<parse_result(parse_stream)> parser;
Run Code Online (Sandbox Code Playgroud)

这使得解析器组合器很好,例如:

parser operator &(parser a, parser b) { return both(a,b); }
Run Code Online (Sandbox Code Playgroud)

但我想要两个功能:

1)我希望自动将字符串文字提升为解析器,以便您可以执行以下操作:

parser option = "<" & regexp("[^+>]+");
Run Code Online (Sandbox Code Playgroud)

2)我希望解析器有一个名称,我可以用它来进行错误格式化.在上面的"both"解析器的情况下,我可以打印我预期的a.name()和b.name().

到目前为止我尝试过的两个选项是

  1. 一个可调用的解析器类,这让我可以从字符串和std :: function实例构建,但是一般的callable必须首先转换为std :: function并从那里转换为解析器,而C++不会进行两次隐式转换

  2. 继承自std :: function所以我可以隐式转换函数,但这似乎有很多陷阱只是将callables转换为解析器.

有没有人对如何构建这个有任何想法?

c++ parsing c++11 std-function

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