在经历了一个问题后std::bind,我想知道是否有可能保留一个vector由std::bind我创建的函数,因此我可以避免使用std::function它和它的重量级包装.
#include <iostream>
#include <functional>
#include <typeinfo>
#include <vector>
int add(int a, int b) {return a + b;}
int main() {
//I believe this here is just a special type of bound function.
auto add2 = std::bind(add, std::placeholders::_1, 2);
auto add3 = std::bind(add, std::placeholders::_1, 3);
//Yup.
std::cout << typeid(add2).name() << std::endl;
//Here's the type of the second function
std::cout << typeid(add3).name() << std::endl;
//Is there a nicer way to do …Run Code Online (Sandbox Code Playgroud) 我正在尝试用 C++ 编写观察者模式,因此我有一个包含 eventname -> 回调函数向量的映射
回调函数存储在向量中,如下所示
std::function<void(void *)>
Run Code Online (Sandbox Code Playgroud)
所以地图看起来像
std::unordered_map<std::string, std::vector<std::function<void(void *)>>>
Run Code Online (Sandbox Code Playgroud)
我可以向向量添加侦听器并接收和响应事件通知。我的问题是实施分离。
所以 std::function 无法比较,因此擦除/删除已不再适用,所以我想搜索向量并手动比较。
我发现这个问题使用 std::function::target 成功地访问了底层指针,但我不能使用它,因为我使用 std::bind 来初始化回调:
std::function<void(void *)> fnCallback = std::bind(&wdog::onBark, this, std::placeholders::_1)
Run Code Online (Sandbox Code Playgroud)
我只想比较底层成员函数 ptr,甚至与该成员函数关联的底层对象 ptr 进行比较。有什么办法吗?
我想避免将成员 fn ptr 包装在包含哈希的对象中,尽管看起来我可能必须这样做......
虽然std::function是可移动的,但在某些情况下它是不可能的或不方便的.复制它有重大的惩罚吗?
它是否可能取决于捕获变量的大小(如果它是使用lambda表达式创建的)?它是依赖于实现的吗?
当泛型 lambda 被存储为 a 时std::function,我们需要提供一个具体的类型,比如,
std::function<double(double)>
Run Code Online (Sandbox Code Playgroud)
因此绑定到特定类型,
以下声明:
std::function<auto(auto)>
Run Code Online (Sandbox Code Playgroud)
引发编译器错误。
我知道,从 c++14 开始,auto可用于存储 lambda 的返回值,但是在将 lambda 存储在std::function.
考虑以下代码片段:
#include <functional>
namespace ns {
struct Arg{};
using Func = std::function<int(Arg)>;
Func operator+(Func lhs, Func rhs) {
return [lhs, rhs](Arg arg) {
return lhs(arg) + rhs(arg);
};
}
}
int main() {
ns::Func foo = [](ns::Arg i) {return 5;};
ns::Func bar = [](ns::Arg i) {return 2;};
auto foobar = foo + bar;
return foobar(ns::Arg());
}
Run Code Online (Sandbox Code Playgroud)
上面的代码使用各种编译器进行编译。相反,以下代码段不会编译。唯一的区别是Func(Argvs int)内部使用的参数类型:
#include <functional>
namespace ns {
using Func = std::function<int(int)>;
Func operator+(Func lhs, Func rhs) {
return [lhs, …Run Code Online (Sandbox Code Playgroud) 我遇到了一个问题。当我使用类似的东西时,std::function<A(Fs...)>它不起作用,但std::function<A(Fs..., B)>确实起作用。这是在 Clang 8.0 下;它在 GCC 下都不起作用。这是示例:
#include <functional>
template<typename A, typename B, typename ...Fs>
void func_tmpl1(std::function<A(Fs..., B)> callable)
{
}
template<typename A, typename ...Fs>
void func_tmpl2(std::function<A(Fs...)> callable)
{
}
class Cls1{};
void func0(std::function<void(float, Cls1)> callable)
{
}
int main()
{
std::function<void(float, Cls1)> f1 = [](float a, Cls1 b){};
func0(f1);
func0([](float a, Cls1 b){});
func_tmpl1<void, Cls1, float>(f1); // fails in GCC
func_tmpl2<void, float, Cls1>(f1);
func_tmpl1<void, Cls1, float>( // fails in GCC
[](float a, Cls1 b)
{ …Run Code Online (Sandbox Code Playgroud) 我试图将一个指向谓词函数的指针传递给Foo和Bar函数。该Bar函数工作正常,但该Foo函数引发编译时错误:
错误:没有匹配的调用函数
Foo<int>(bool (&)(int))
为什么编译器会引发错误?' 解包后' Foos 和Bar's 模板参数类型之间有什么区别Args吗?
#include <functional>
bool predicate(int a) {
return (a > 5);
}
// sizeof...(Args) == 1 and I suppose it is int
template<typename... Args>
void Foo(std::function<bool(Args...)> predicate) {
// clang: note: candidate template ignored:
// could not match 'function<bool (int, type-parameter-0-0...)>'
// against 'bool (*)(int)'
}
template<typename Args>
void Bar(std::function<bool(Args)> predicate) {
}
int main(int argc, char const *argv[]) …Run Code Online (Sandbox Code Playgroud) c++ templates type-inference variadic-templates std-function
尝试std::bind()使用以下代码获取函数对象:
driver_manager driverManager();
std::function<void(mqtt::const_message_ptr,
mqtt::async_client*,callback*,sql::Driver*)> fn = std::bind(&driver_manager::test_callback, &driverManager, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
Run Code Online (Sandbox Code Playgroud)
结果出错:
错误:从'std::_Bind_helper<false, void (driver_manager::*)(std::shared_ptr<const mqtt::message>, mqtt::async_client*, callback*, sql::Driver*), driver_manager ( *)()、const std::_Placeholder<1>&、const std::_Placeholder<2>&、const std::_Placeholder<3>&、const std::_Placeholder<4>&>::type'非标量类型 'std::function<void(std::shared_ptr<const mqtt::message>, mqtt::async_client*, callback*, sql::Driver*)>' 请求
几个小时以来,我一直试图找出问题所在,这段代码有什么问题?
编辑
driver_manager.hpp
class driver_manager{
public:
driver_manager();
void test_callback(mqtt::const_message_ptr, mqtt::async_client*,callback*,sql::Driver*);
};
Run Code Online (Sandbox Code Playgroud)
driver_manager.cpp
driver_manager::driver_manager(){
}
void driver_manager::test_callback(mqtt::const_message_ptr msg, mqtt::async_client *client, callback *cb, sql::Driver *driver){
std::cout << "Callback triggered" << std::endl;
}
Run Code Online (Sandbox Code Playgroud) 许多主题告诉我们,使用像 lambda 表达式这样的小对象可以避免在使用std::function. 但我的研究表明并非如此。
这是我的实验代码,很简单
#include <iostream>
#include <functional>
using namespace std;
typedef std::function<int(int, int)> FUNC_PROTO;
class Test
{
public:
int Add(int x, int y) { return x + y; }
};
int main()
{
Test test;
FUNC_PROTO functor = [&test](int a, int b) {return test.Add(a, b); };
cout << functor(1, 2) << endl;
}
Run Code Online (Sandbox Code Playgroud)
我在centos7上编译它,gcc版本4.8.5 20150623但是valgrind显示了这一点:
==22903== HEAP SUMMARY:
==22903== in use at exit: 0 bytes in 0 blocks
==22903== total heap usage: 1 allocs, 1 frees, …Run Code Online (Sandbox Code Playgroud) 考虑下面的类:
template <class T>
struct Test
{
Test() {
if (!f) {
f = []() { std::cout << "it works\n"; };
initialized = true;
}
}
static void check() {
if (f) f();
else std::cout << "f is empty\n";
}
T x{};
inline static std::function<void()> f;
inline static bool initialized = false;
};
Run Code Online (Sandbox Code Playgroud)
此类的对象,如果全局声明(是的,我知道使用全局变量是一种不好的做法f),则在初始化后似乎会清空该函数。以下示例演示了这一点:
Test<double> t;
int main()
{
t.x = 1.5;
std::cout << "t.x = " << t.x << "\n";
std::cout << std::boolalpha << "initalized: " …Run Code Online (Sandbox Code Playgroud)