c++ - 在模板函数参数中使用 std::bind
问题描述
以前可能以某种方式问过这个问题,但我找不到正确的搜索关键字。
在编写测试函数时,我决定将测试代码重构为模板函数:
#include <iostream>
#include <functional>
#include <utility>
#include <vector>
template <typename In, typename Exp >
void runTest (
std::pair<In, Exp> testParams,
Exp (*testFunction)(In)
/*std::function< Exp(In)> testFunction */ )
{
Exp result = testFunction(testParams.first);
std::cout << "Result : " << (result == testParams.second? "SUCCESS":"FAILURE")
<< " expected : " << testParams.second
<< " got : " << result
<< std::endl;
}
用输入和预期结果填充一个向量,并将这些对与我们要测试的函数一起传递。非常适合一个功能:
long f1 (long a1)
{
return a1 + 100;
}
void testf1()
{
std::vector<std::pair<long, long> > testCases = {
{100,200},
{300,400}
};
for (auto test : testCases) {
runTest (test, f1);
}
}
但后来不得不测试一个需要两个参数的。“好吧,没问题,我会 std::bind1st ......哦,那已经被弃用了...... std::bind 应该给它,对吧?第一个参数并将它传递给runTest
“......
long f2 (long a1, long a2)
{
return a1+a2;
}
void testf2()
{
long a1 = 1234;
std::vector<std::pair<long, long> > testCases = {
{0,1234},
{2,1238},
{11,1245}
};
for (auto test : testCases){
auto f2bound = std::bind(f2, a1, std::placeholders::_2);
runTest (test, f2bound);
}
}
但是编译器说“不”:
~/src/cpplay/onestens$ g++ -m64 --std=c++11 -o soq.out soQuestionBind.cpp -g
soQuestionBind.cpp: In function ‘void testf2()’:
soQuestionBind.cpp:50:31: error: no matching function for call to ‘runTest(std::pair<long int, long int>&, std::_Bind<long int (*(long int, std::_Placeholder<2>))(long int, long int)>&)’
runTest (test, f2bound);
^
soQuestionBind.cpp:7:6: note: candidate: template<class In, class Exp> void runTest(std::pair<_T1, _T2>, Exp (*)(In))
void runTest (
^
soQuestionBind.cpp:7:6: note: template argument deduction/substitution failed:
soQuestionBind.cpp:50:31: note: mismatched types ‘Exp (*)(In)’ and ‘std::_Bind<long int (*(long int, std::_Placeholder<2>))(long int, long int)>’
runTest (test, f2bound);
^
我有点落后于 C++11(以及 14 和 17),但这应该是可能的,对吧?
我猜 std::bind 返回的对象不能被强制转换为简单的函数指针......那么我的模板参数必须如何定义才能接受绑定函数?
解决方案
我猜 std::bind 返回的对象不能被强制转换为简单的函数指针。
正确的。
获取通用可调用对象的典型方法是使用简单的模板参数。无需使用函数指针std::function
或其他任何东西:
template <typename T, typename U, typename F>
void runTest (
std::pair<T, U> testParams,
F testFunction )
{
auto result = testFunction(testParams.first);
// do something ...
}
现在您可以使用std::bind
,但我建议您改用 lambda。
推荐阅读
- php - 通过 HTTP POST 数据之间的区别
- javascript - 根据输入元素范围更改 div-element
- scala - 错误:值写入不是 Unit 的成员
- c# - 有没有使用 python 库从 Windows 操作系统上的 GUI 中提取数据的好方法?
- elasticsearch - 弹性搜索中的前缀查询不起作用
- c++ - C++:为什么我第一次调用 rand() 重复相同的数字,而第二次调用不是?
- react-native - 如何将文件从android资产文件夹复制到android文档目录路径
- react-native - React-Native NetInfo 在一次工作后不起作用?
- html - 使用 CSS 制作响应式表格
- flutter - Flutter - 如何将 DropDownMenuItem 定位在 DropDownMenuButton 下方?