我目前正在处理一个我正在链接函数对象的库.
我正在创建一个函数模板,它接受一个可调用的对象(此刻为std :: function),并在函数的输出和输入类型上进行参数化.这是我定义的简化版本:
template <typename In, typename Out>
std::vector<Out> process(std::vector<In> vals, std::function< Out(In) > func)
{
// apply func for each value in vals
return result;
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是使用问题.似乎当我传递lambda时,编译器无法正确推断出类型,因此抱怨该函数不存在:
std::vector<string> strings;
// does NOT compile
auto chars = process(strings,
[]( std::string s ) -> char
{
return s[0]; // return first char
}
);
Run Code Online (Sandbox Code Playgroud)
如果我明确地将lambda包装进去std::function,程序将编译:
std::vector<string> strings;
// DOES compile
auto chars = process(strings,
std::function< char(std::string) >(
[]( std::string s ) -> char
{
return s[0]; // return …Run Code Online (Sandbox Code Playgroud) 如何使用单个函数将任意动态链接库(dll)函数加载到std::function对象中?
例如,我想将两个函数编译成一个dll:
// test.dll
int plusFive(int value) {
return value + 5;
}
void printHello() {
std::cout << "Hello!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
并在运行时使用以下单个函数加载它们:
// main.cc
#include <functional>
int main() {
std::function<int(int)> func1(loadDllFunc("test.dll", "plusFive"));
std::function<void()> func2(loadDllFunc("test.dll", "printHello"));
}
Run Code Online (Sandbox Code Playgroud) 这是一个理论问题.假设有一些对象包含订阅这些对象事件的回调函数列表.现在我们要将这些对象存储在磁盘上.是可std::function序列化的吗?
我有一个结构,我传递给我的应用程序,其中包含一堆回调函数:
typedef struct {
std::function<void (void)> f1;
std::function<void (int)> f2;
std::function<int (float *)> f3;
// ... and so on
} CallbackTable;
Run Code Online (Sandbox Code Playgroud)
我通过将不同的函数绑定到各种回调来处理应用程序中的状态控制,具体取决于当前的系统状态; 它工作正常.
我现在要做的是添加一些带有包含可变数量参数的签名的额外回调,类似于printf:例如,
std::function<int (const char * format, ...)> printToStdOut;
Run Code Online (Sandbox Code Playgroud)
这不起作用.在Visual C++中,我收到一条错误消息,指出:
error C2027: use of undefined type 'std::_Get_function_impl<_Fty>'
Run Code Online (Sandbox Code Playgroud)
我仍然在感受这个C++语法领域,并且非常感谢我对如何从这里开始的任何建议.我的首要目标是能够按以下方式拨打电话:
myCallbackTable.printToStdOut("I've just eaten %d bananas\r\n", nBananas);
Run Code Online (Sandbox Code Playgroud)
...并根据系统状态将输出定向到控制台,文件或GUI窗口.
我正在讨论在C++中实现策略模式的最佳方法.到目前为止,我一直使用标准方式,其中上下文具有指向基本策略类的指针,如下所示:
class AbstractStrategy{
public:
virtual void exec() = 0;
}
class ConcreteStrategyA{
public:
void exec();
}
class ConcreteStrategyB{
public:
void exec();
}
class Context{
public:
Context(AbstractStrategy* strategy):strategy_(strategy){}
~Context(){
delete strategy;
}
void run(){
strategy->exec();
}
private:
AbstractStrategy* strategy_;
Run Code Online (Sandbox Code Playgroud)
由于有指向对象的指针可能会导致不良行为,我一直在寻找一种更安全的方式来实现这种模式,我发现这个问题在哪里std::function被提议作为处理这种模式的更好方法.
有人可以更好地解释一下如何std::function运作,也许有一个战略模式的例子?
我有麻烦搞清楚这两个函数包装之间的差异std::function和std::mem_fn.从描述中,在我看来,std :: function确实std::mem_fn做到了.在这种情况下将一个使用std::mem_fn过std::function?
我看过很多类似的问题,但还没有找到解决我特定问题的方法.我试图SWIGify一些使用std :: function的C++ 11代码,所以我可以在我的Java应用程序中使用它.
我遇到过像这样的共享指针:
virtual std::shared_ptr<some::ns::TheThing> getTheThing(unsigned short thingID);
Run Code Online (Sandbox Code Playgroud)
并使用shared_ptr指令成功处理它们,如下所示:
%shared_ptr(some::ns::TheThing);
Run Code Online (Sandbox Code Playgroud)
我遇到过这样的共享指针向量:
virtual std::vector<std::shared_ptr<some::ns::TheThing>> getAllTheThings() const = 0;
Run Code Online (Sandbox Code Playgroud)
并使用如下模板成功处理它们:
%template(ThingVector) std::vector<std::shared_ptr<some::ns::TheThing>>;
Run Code Online (Sandbox Code Playgroud)
现在我有一个像这样的方法:
void registerThingCallback(std::function<void(std::shared_ptr<some::ns::TheThing>) > func);
Run Code Online (Sandbox Code Playgroud)
我无法让SWIG正确包装它.我已经尝试使用%回调,导演,%模板和%内联功能代码,因为我已经看到所有这些事情的例子,但是还没有能够得到任何似乎接近工作的东西.如果有帮助(清理和减少),这里有一个关于函数调用的更多上下文:
#include <functional>
namespace some {
namespace ns {
/**
* Hold some callbacks.
*/
class ThingCallbacks {
public:
/**
* Registers a callback
* @param func The callback function
*/
void registerThingCallback(std::function<void(std::shared_ptr<some::ns::TheThing>) > func);
};
}
}
Run Code Online (Sandbox Code Playgroud)
根据Flexo下面的答案,我更接近解决方案.我能够让下面的例子完全像宣传的那样工作.我尝试将它合并到我的实际代码中,但遇到了问题.为了扩展我之前的简化示例,这里是我对TheThing的定义:
#ifndef THE_THING_H
#define THE_THING_H
#include <string>
namespace some {
namespace ns …Run Code Online (Sandbox Code Playgroud) 的std::function类型擦除构造被定义为:
template< class F >
function( F f );
Run Code Online (Sandbox Code Playgroud)
赋值运算符定义为:
template< class F >
function& operator=( F&& f );
Run Code Online (Sandbox Code Playgroud)
(来源cppreference)
为什么构造函数获得f由价值而operator=获得f通过转发的参考?
随着即将推出的带有auto的非类型模板参数的 C++ 17特性,是否可以以std::function能够放置例如以下函数的方式实现:
bool f(int n, double d) {}
bool g(bool b, char c) {}
bool h(bool b) {}
Run Code Online (Sandbox Code Playgroud)
进入自动模板化的std::function对象:
std::function<bool(auto, auto)> faa = f; // ok
std::function<bool(int, auto)> fia = f; // ok
std::function<bool(double, auto)> fda = f; // error: function type mismatch
std::function<bool(auto, auto)> gaa = g; // ok
std::function<bool(auto, auto)> haa = h; // error: function type mismatch
std::function<bool(auto)> ha = h; // ok
Run Code Online (Sandbox Code Playgroud)
等等.
换句话说,让std::function对象受限于他们接受的函数类型? …
我有以下问题:
template< std::size_t N >
class A
{
std::function< std::size_t( /*std::size_t,....,std::size_t <- N-times*/) > foo;
};
Run Code Online (Sandbox Code Playgroud)
正如您在上面所看到的,我尝试将a声明std::function<...> foo为类的成员A.在这里,我希望foo具有返回类型std::size_t(这没有问题)并且作为输入,我将传递N次类型std::size_t但我不知道如何.有可能吗?
提前谢谢了.