我围绕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++创建一个简单的信号/插槽系统,但是当我尝试将它与参数一起使用时,我遇到了一些问题,这是我的代码:
我的信号类:
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) 我有一个函数应该返回与该函数相同类型的std ::函数.基本上我想要这样的东西:
using RetType = std::function<RetType(void)>;
Run Code Online (Sandbox Code Playgroud)
这显然不会编译.如何正确声明返回类型?
我想创建一个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这样的方式轻松初始化对象:当被调用时,它们什么也不做,而不是抛出异常.这可能吗?
我正在努力使用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很新,我尝试了我已经知道的但是我总是遇到编译错误.
那怎么办呢?
我正在尝试创建一个模板函数,可以通过任何类型和数量的参数传递一些其他函数并将其绑定到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) 我对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) 假设我有一个包含三个成员函数的类,如下所示:
#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"调用.但是,我不认为我使用正确的语法,因为当我尝试编译它时,我收到一条错误,说"非标准语法;使用'&'创建指向成员的指针." 我不太确定会出现什么问题,因为如果这些函数不是类中的成员函数(只是命名空间中定义的常规函数),则此方法可以正常工作. 那么是否可以将成员函数传递给另一个成员函数?
我听说费用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) 我正在研究一个解析器组合库,我真的很喜欢我的解析器只是一个可调用的对象:
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().
到目前为止我尝试过的两个选项是
一个可调用的解析器类,这让我可以从字符串和std :: function实例构建,但是一般的callable必须首先转换为std :: function并从那里转换为解析器,而C++不会进行两次隐式转换
继承自std :: function所以我可以隐式转换函数,但这似乎有很多陷阱只是将callables转换为解析器.
有没有人对如何构建这个有任何想法?
std-function ×10
c++ ×9
c++11 ×7
lambda ×3
auto ×1
boost-asio ×1
boost-thread ×1
function ×1
parsing ×1
shared-ptr ×1
signals ×1
templates ×1