当推断的返回类型是std :: nullptr_t时,为什么允许第二个赋值?使用函数指针,这是禁止的.
为什么第二个lambda不运行?
#include <cstdio>
#include <functional>
int main()
{
std::function<void* ()> f;
f = []() -> void* {
printf ("runs\n");
return nullptr;
};
f();
f = []() {
printf ("doesn't run\n");
return nullptr; // -> std::nullptr_t
};
f();
return 0;
}
Run Code Online (Sandbox Code Playgroud) (注意: 正如标签中已经清楚的那样,这是严格的 C++ 03. 是的,我知道,lambda会让所有这些痛苦消失(带来新的种类,我打赌),但这是一个嵌入式系统,有一个90年代的操作系统版本,我被告知我应该很高兴我有一个C++ 03编译器(GCC4.1.x,BTW)或C++编译器.所以请不要发布C++ 11解决方案,无需擦它,真的.
另外,std::bind(),std::function()等等,当然,实际std::tr1的,但我编辑了的 tr1前缀,因为我认为这增加了大多只有噪声的代码.)
我有一些类似服务器的东西,我需要注册函数,我需要调整它们来调用一些对象类似但略有不同的函数.这些函数具有不同的参数列表.服务器"知道"当我尝试注册一个函数时,它只接受一个具有正确签名的函数(根据std::function需要正确),这取决于作为模板参数传入的一些魔术标记.
这是代码的草图:
// this I just use
class server {
public:
template<unsigned int MagicTag>
bool register_call(typename some_traits_type<MagicTag>::func_type);
};
// this needs to be called from the server
class X {
public:
bool foo();
bool bar(std::string&);
bool baz(int);
};
// this is the glue
class Y {
public:
Y(X& x) : x_(x) {
register_call<MAGIC_FOO>(&Y::foo );
register_call<MAGIC_BAZ>(&Y::bar, _1);
register_call<MAGIC_FBZ>(&Y::baz, _1); …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个简单的调度程序,用户代码可以将回调附加到它.每个事件都有一个已知的签名,用户代码需要使用正确的数字和参数类型调用dispatch.这由可变参数管理.但是,freestandingInt不被接受,因为向量不是正确的类型.如何使它通用?
遵循一个最小的例子
void freestanding() {
std::cout << "freestanding" << std::endl;
}
void freestandingInt(int iArg) {
std::cout << "freestandingInt " << iArg << std::endl;
}
struct Dispatcher {
typedef struct Event_ {
std::vector<std::function<void()> > listeners;
} Event;
template<class... Args>
void dispatch(int eventNr, Args&&... args) {
for (auto listener: events[eventNr].listeners) {
std::function<void()> f(std::bind(listener, std::forward<Args>(args)...));
f();
}
}
std::map<int, Event> events;
};
int main (int argc, char **argv) {
Dispatcher disp;
disp.events[0].listeners.push_back(freestanding);
disp.dispatch(0); // OK
// error here
//disp.events[1].listeners.push_back(freestandingInt);
}
Run Code Online (Sandbox Code Playgroud) 是否可以使用std :: async调用使用std :: bind创建的函数对象.以下代码无法编译:
#include <iostream>
#include <future>
#include <functional>
using namespace std;
class Adder {
public:
int add(int x, int y) {
return x + y;
}
};
int main(int argc, const char * argv[])
{
Adder a;
function<int(int, int)> sumFunc = bind(&Adder::add, &a, 1, 2);
auto future = async(launch::async, sumFunc); // ERROR HERE
cout << future.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误是:
没有用于调用'async'的匹配函数:忽略候选模板:替换失败[使用Fp = std :: _1 :: function&,Args = <>]:'std :: _1 :: __ invoke_of中没有名为'type'的类型 …
我一直在使用Loki的Functor,我最近问了一个关于它的问题(仍然没有答案......)我被告知要使用std :: function,但我更喜欢Loki的Functor实现,因为它也适用于各种各样的指针作为参数(例如std :: shared_ptr).
struct Toto
{
void foo( int param )
{
std::cout << "foo: " << param << std::endl;
}
};
int
main( int argc, const char** argv )
{
std::shared_ptr<Toto> ptr = std::make_shared<Toto>();
Loki::Functor<void, LOKI_TYPELIST_1(int)> func( ptr, &Toto::foo );
func(1);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法用std :: function做到这一点?
std::function已知存在性能问题,因为它可能会进行堆分配。承认,如果您是 100% 诚实的,那么在大多数情况下,一个堆分配应该几乎不是问题……但是让我们假设在特定情况下进行堆分配是不可取的或禁止的。也许我们正在做几百万次回调并且不想要几百万次堆分配,无论如何。
所以......我们想避免堆分配。
Dobbs 博士的文章Efficient Use of Lambda Expressions 和 std::function给出了std::function通过利用标准推荐并在每个主流标准库中实现的小对象优化来优化使用的建议。
这篇文章详细解释了标准库必须如何复制函子,因为std::function对象可能比原始函子的寿命长(尽管std::ref如果你确定它没有,你可以使用),这将是一个糟糕的魔力。此外,需要复制捕获,这是问题:事先不知道闭包的确切类型(或其大小),因为它可能是具有任意数量捕获的任何类型的闭包,因此必须做出一些妥协。达到特定大小时,捕获将保存在function对象内的存储中,超出此大小将动态分配。存储空间很小,从 12 到 16 字节不等,因此假设是 64 位构建,最多有两个指针(不包括实际的函数指针)。
因此,Dobbs 博士建议(并且其他几个站点都采纳了该建议,似乎没有太多反对意见)捕获对结构的引用,该结构包含对您实际想要捕获的内容的引用。这样,您只捕获一个引用,这是完美的,因为它始终适合小对象存储。
这是如何运作的?首先需要复制东西的假设是function对象可能比原始闭包的作用域更长。当然,这意味着它也比它持有引用的结构以及从该结构内部引用的任何内容的生命周期更长。
这应该如何工作?既然我看不到它是如何工作的,有没有更好的知名配方来解决这个问题?(一个不引用无效对象的对象)
考虑这个伪代码段:
class SomeClass
{
public:
SomeClass()
{
if(true)
{
fooCall = [](auto a){ cout << a.sayHello(); };
}
else
{
fooCall = [](auto b){ cout << b.sayHello(); };
}
}
private:
template<typename T>
std::function<void(T)> fooCall;
};
Run Code Online (Sandbox Code Playgroud)
我想要的是一个fooCall存储泛型lambda 的类成员,而lambda又在构造函数中赋值.
编译器抱怨fooCall不能是模板化的数据成员.
关于如何在类中存储泛型lambda,有没有简单的解决方案?
我发现,将lambda函数转换为std::function<>值的相对少量代码的编译时间可能非常高,特别是对于Clang编译器.
考虑以下创建100个lambda函数的虚拟代码:
#if MODE==1
#include <functional>
using LambdaType = std::function<int()>;
#elif MODE==2
using LambdaType = int(*)();
#elif MODE==3
#include "function.h" // https://github.com/skarupke/std_function
using LambdaType = func::function<int()>;
#endif
static int total=0;
void add(LambdaType lambda)
{
total += lambda();
}
int main(int argc, const char* argv[])
{
add([]{ return 1; });
add([]{ return 2; });
add([]{ return 3; });
// 96 more such lines...
add([]{ return 100; });
return total == 5050 ? 0 : 1;
}
Run Code Online (Sandbox Code Playgroud)
根据MODE预处理器宏,该代码可以在以下三种方式之间进行选择,以便通过lambda函数传递 …
为什么我不能有一个std::set或std::unordered_set的std::functionS'
有什么方法可以让它工作吗?
我正在尝试绑定一些ta-lib函数,然后回调。
这是简化的示例代码:
#include <functional>
#include <type_traits>
#include <cstdint>
struct DataChunk {
// ...
};
typedef uint64_t idx_t;
template <typename LookbackArgType> // int, double
struct talib_traits {
using talib_lookback_t = std::function<int(LookbackArgType)>;
using talib_function_t = std::function<void(DataChunk &, void *, idx_t, idx_t, LookbackArgType)>;
};
template <>
struct talib_traits<void> {
using talib_lookback_t = std::function<int()>;
using talib_function_t = std::function<void(DataChunk &, void *, idx_t, idx_t)>;
};
struct X {
talib_traits<int>::talib_lookback_t talib_lookback_int = nullptr;
talib_traits<int>::talib_function_t talib_function_int = nullptr;
talib_traits<double>::talib_lookback_t talib_lookback_double = nullptr;
talib_traits<double>::talib_function_t talib_function_double = …Run Code Online (Sandbox Code Playgroud)