c++ - C++17 不能使用 std::bind 生成 std::function
问题描述
我有一个Register
以 astd::function<void(const uint8_t* data, size_t len)>
作为参数的函数。我想使用对象的成员函数作为目标。
我发现this question根据它的答案是使用std::bind
将第一个参数(隐式this
指针)绑定到实际的对象指针,然后将其用作std::function
参数。
然而,这在 C++11、C++14 和 C++17 中都不再起作用了吗?
考虑以下测试程序。
#include <iostream>
#include <cstdint>
#include <functional>
void Register(std::function<void(const uint8_t* data, size_t len)> func) {
//Dummy - directly call into function
func(nullptr, 0);
}
class TestClass {
public:
void TestRegister() {
Register(
std::bind(&TestClass::TestTarget, this, std::placeholders::_1)
);
}
void TestTarget(const uint8_t* data, size_t len) {
(void) data;
(void) len;
std::cout << "Hello there" << std::endl;
}
};
int main() {
TestClass testObj;
testObj.TestRegister();
return 0;
}
当为此编译时-std=c++17
会抛出一个相当神秘的错误消息(我不知道它在这里试图说什么Wrong number of arguments for pointer-to-member
):
In file included from /home/max/Documents/TestingFunctions/main.cpp:3:0:
/usr/include/c++/7/functional: In instantiation of ‘struct std::_Bind_check_arity<void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>’:
/usr/include/c++/7/functional:854:12: required from ‘struct std::_Bind_helper<false, void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>’
/usr/include/c++/7/functional:875:5: required by substitution of ‘template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (TestClass::*)(const unsigned char*, long unsigned int); _BoundArgs = {TestClass*, const std::_Placeholder<1>&}]’
/home/max/Documents/TestingFunctions/main.cpp:14:78: required from here
/usr/include/c++/7/functional:841:7: error: static assertion failed: Wrong number of arguments for pointer-to-member
static_assert(_Varargs::value
^~~~~~~~~~~~~
/home/max/Documents/TestingFunctions/main.cpp: In member function ‘void TestClass::TestRegister()’:
/home/max/Documents/TestingFunctions/main.cpp:14:26: error: could not convert ‘std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (TestClass::*)(const unsigned char*, long unsigned int); _BoundArgs = {TestClass*, const std::_Placeholder<1>&}; typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type = std::_Bind<void (TestClass::*(TestClass*, std::_Placeholder<1>))(const unsigned char*, long unsigned int)>](((TestClass*)this), std::placeholders::_1)’ from ‘std::_Bind_helper<false, void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>::type {aka std::_Bind<void (TestClass::*(TestClass*, std::_Placeholder<1>))(const unsigned char*, long unsigned int)>}’ to ‘std::function<void(const unsigned char*, long unsigned int)>’
std::bind(&TestClass::TestTarget, this, std::placeholders::_1)
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
将函数替换为TestRegister
在 lambda 表达式中执行完全相同操作的函数可以编译并运行而不会出现问题。
void TestRegister() {
Register(
[this](const uint8_t* data, size_t len) {
TestTarget(data, len);
}
);
}
问题:为什么std::bind
链接问题的方法不起作用?是否删除了此功能或者我的代码中有错误?
解决方案
您的函数Register
需要一个具有两个参数的函数,但您尝试将一个具有一个占位参数的函数传递给它。
void TestRegister() {
Register(
std::bind(&TestClass::TestTarget, this, std::placeholders::_1, std::placeholders::_2)
);
}
推荐阅读
- javascript - 是否可以在不显示在页面/画布上的情况下获得图形的基数 64(Graph.Js)
- git - 如何说服 Xcode 11.5 在 Project Navigator 中显示我的 README.md?
- java - Bazel 挂在 java 二进制文件上
- excel - vbscript 为特定用户名以读/写模式打开共享文件并保持其他用户具有打开只读模式的权限
- rust - 如何通过具有不同类型的 trait 方法获取结构值?
- python - 在 Python 中使用 * 删除特定扩展名的文件
- javascript - 如何从 JavaScript 中的新日期中减去或添加 GMT 数字?
- docker - 如何将文件从 git 复制到詹金斯的远程 docker 容器?
- r - 如何在R中的circlize chordDiagram上更改标签字体大小
- python - 如何使用 seaborn 制作相关热图但按特定列过滤?