如何正确地将comparator传递给另一个模板函数
How properly pass comparator to another template function
我需要一个函数,它将接受两个迭代器和一个自定义比较器来比较这两个迭代器的值。我不想为此使用额外的模板参数。我是这样实现的:
template<typename T>
void foo(T begin, T end,
function<bool(decltype(*begin), decltype(*begin))> compare = less<decltype(*begin)>())
{
// I want to use 'compare' as: "compare(*begin, *begin);"
}
这段代码已经被clang正常编译,但在GCC 5.4.0上我有一些错误:
binary_heap.cpp:10:79: error: local variable 'begin' may not appear in this context
function<bool(decltype(*begin), decltype(*begin))> compare = less<decltype(*begin)>())
^
binary_heap.cpp:10:85: error: template argument 1 is invalid
function<bool(decltype(*begin), decltype(*begin))> compare = less<decltype(*begin)>())
如何纠正这段代码,使其可以成功地在clang和GCC上编译?或者也许有一个更合适的解决方案来定义这样的函数?
您不能在默认实参中使用形参,即使在未求值的上下文中也是如此(尽管可能应该修改标准以放宽该限制)。代替decltype(*begin)
,使用
decltype(*std::declval<T&>())
编辑:实际上,这可能不会做您想要的,因为如果应用*
操作符产生左值,那么decltype
说明符将解析为左值引用,但是您希望未引用类型作为std::less
的参数。最好使用:
typename std::iterator_traits<T>::value_type
编辑2:我同意krzaq,最好只是添加另一个模板参数
仅仅通过强制使用function
(更多细节在这里),就会大大降低算法的性能。只需要模板推导出Compare
,你就可以了:
template<typename T, typename Compare = std::less<typename iterator_traits<T>::value_type>>
void foo(T begin, T end, Compare compare = {})
{
// I want to use 'compare' as: "compare(*begin, *begin);"
}
有趣的是,标准算法通过按值而不是转发引用强制/建议使用轻量级函子。
要回答实际的问题:您可以使用std::less<>
,它默认为std::less<void>
,并模板化operator()
进行实际的比较:
template<typename T>
void foo(T begin, T end,
function<bool(decltype(*begin), decltype(*begin))> compare = less<>())
{
// I want to use 'compare' as: "compare(*begin, *begin);"
}
新增模板参数Compare
。这使得编译器更容易内联。当我在它支持哨兵。
template<class It, class Sentinel, class Compare=std::less<void>>
void foo(It begin, Sentinel end, Compare cmp={}) {
}
但是,假设c++ 14,排除上述情况,我会这样做:
template<class T>
using comparator_sig = bool(T const&,T const&);
template<class T>
using comparator = std::function<comparator_sig<T>>;
template<class It>
using compare_inside_it = comparator<
typename std::iterator_traits<It>::value_type
>;
template<typename T>
void foo(T begin, T end, compare_inside_it<T> compare = less<>) {
}
C++11中的,我会写我自己的less<void>
:
struct compare_less {
template<class T>
bool operator()( T const& lhs, T const& rhs ) const {
return std::less<T>{}(lhs, rhs);
}
};
和做的事:
template<typename T>
void foo(T begin, T end, compare_inside_it<T> compare = compare_less{}) {
}
或者直接做:
template<typename T>
void foo(T begin, T end, compare_inside_it<T> compare = {}) {
if (!compare) compare=compare_less{};
}
相关文章:
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 将 N-arg 函数包装到另一个函数中
- C++从另一个函数退出函数
- 视觉我希望一个函数在另一个函数C++中进行计算
- 在另一个函数 (c++) 中调用变量
- 如何在另一个函数中使用返回值作为参数?
- 如何包装一个函数以适应另一个函数的所需类型
- 当使用我在一个函数、另一个函数中修改的数组时,在我的输出中得到一个奇怪的负数
- 如何将 lambda 函数作为参数发送到另一个函数
- 将可变参数从一个函数传递到另一个函数
- 有没有办法在另一个函数中加入线程?(即超出其自身范围)
- 存储另一个函数返回的布尔数组时遇到问题
- 我正在尝试将表的地址传递给要在另一个函数中使用的指针,但得到不兼容的指针类型
- 如何在C++中提供模板化函数作为另一个函数的参数,默认值?
- 将作业传递给另一个函数,而不会延迟 arduino
- 编译器在C++中调用另一个函数时,在参数中查找已删除的构造函数
- 将参数从一个函数传递到另一个函数(没有模板) - C++
- 如何利用指针从一个函数到另一个函数?
- 使用另一个函数调用一个函数(都在类中)时出现问题.没有错误代码C++
- 在 c++ 中,如何将当前函数的所有参数传递给另一个函数?