形参使用std::greater或std::less作为实参
Parameter to use std::greater or std::less as argument
我想创建一个函数,其参数接受std::greater<int>
或std::less<int>
作为参数。但是,我被参数的语法卡住了。
这是我尝试的格式:
myFunction(int a, int b, bool *comp(int, int)) { … }
…
std::greater<int> bigger;
myFunction(2, 3, bigger);
但是不起作用,我怀疑第三个参数是完全错误的。它实际上应该是什么?
不能将
std::greater<int>
转化为bool* (*)(int, int)
采用比较器的函数通常通过模板实现:
template <typename Comparator>
myFunction(int a, int b, Comparator comp) { … }
,但你也可以使用std::function
来实现它:
myFunction(int a, int b, std::function<bool (int, int)> ) { … }
第一个版本在头文件中公开代码,但通常性能更好。至于第二个版本,您可以将实现隐藏在.cpp文件中,但是,由于无法内联,您将损失一些性能比较器调用。
所以这里的技巧是std::less
和std::greater
实际上是可以简单构造的无状态函数对象。但是它们不支持转换为函数指针。
有效的选择是(A)通过template
参数获取比较器并在头文件中实现代码:
template<typename C> void myFunc( int a, int b, C comp )
意味着你必须在头文件中实现它,或者(B)通过std::function< bool(int, int) >
:
void myFunc( int a, int b, std::function< bool(int, int) > comp )
有一些成本(可能很大?)(对于无状态std less/greater,可以通过小对象优化来避免堆分配,但无论如何,它往往需要调用virtual
函数,这也会阻塞内联)。
或者(C)编写一些代码,使您可以将无状态函子转换为函数指针:
template<typename T>
using Type = T;
template<typename StatelessFunctor>
struct function_ptr_of_stateless_t {
template<typename R, typename... Args>
operator Type<R(Args...)>*() const {
return [](Args... args)->R {
return StatelessFunctor()(std::forward<Args>(args)...);
};
}
};
template<typename StatelessFunctor>
function_ptr_of_stateless_t<StatelessFunctor> as_function_ptr() {
return {};
}
bool myFunction( int a, int b, bool(*comp)(int, int) ) { return comp(a,b); }
int main() {
std::cout << myFunction(3,7, as_function_ptr<std::less<int>>() ) << "n";
}
其中template
函数as_function_ptr
接受无状态函子的类型,并创建一个throw away类型,允许您将其强制转换为任何兼容的函数指针类型。
这比std::function
解决方案的开销要小一些,因为对函数指针的调用往往比对virtual
方法的调用快,此外,一些编译器(如gcc)在内联函数指针方面相当不错,甚至从一个编译单元到另一个编译单元。
作为附加功能,在c++ 14中可以使用:
int main() {
std::cout << myFunction(3,7, as_function_ptr<std::less<>>() ) << "n";
}
,它仍然可以很好地工作
使用模板:
template<class Callable>
myFunction(int a, int b, Callable f);
- 非类型引用形参/实参
- 成员函数指针的模板实参演绎
- 函数和函数作为模板函数的实参
- Const到非Const指针模板实参的转换
- 传递boost::函数,该函数接受一个模板实参作为默认为NULL的形参
- 当实参是初始化列表而形参是引用时,重载解析
- 函数模板中返回类型的模板实参演绎
- ostream_iterator的模板实参-每个元素都是pair
- c++——关于使用默认实参的困惑
- std::shared_ptr、继承和模板实参演绎的问题
- 将操作符转换为模板实参的特化
- 使用模板模板形参时,模板实参推导失败
- 带有const实参的c++构造函数
- 函数指针作为模板实参而不是函子
- c++临时对象绑定到实参并返回const引用值
- 调用对象作为默认实参的this
- 当涉及一个重载函数作为实参时,模板实参推导是如何工作的
- 将非const引用使用auto-keyword声明的lambda作为实参传递给std::函数形参类型
- 使用std::result_of确定模板实参的返回类型
- 形参使用std::greater或std::less作为实参