C++ 如何正确地将比较器传递给另一个模板函数
我需要一个函数,它将使用两个迭代器和一个自定义比较器来比较这个迭代器的值。我不想为此使用其他模板参数。我以这种方式实现了它:C++ 如何正确地将比较器传递给另一个模板函数,c++,templates,C++,Templates,我需要一个函数,它将使用两个迭代器和一个自定义比较器来比较这个迭代器的值。我不想为此使用其他模板参数。我以这种方式实现了它: template<typename T> void foo(T begin, T end, function<bool(decltype(*begin), decltype(*begin))> compare = less<decltype(*begin)>()) { // I want to use 'compare' a
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);"
}
模板
无效foo(T开始,T结束,
函数compare=less())
{
//我想将“compare”用作:“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)>())
binary\u heap.cpp:10:79:错误:局部变量“begin”可能不在此上下文中出现
函数compare=less())
^
二进制堆.cpp:10:85:错误:模板参数1无效
函数compare=less())
如何更正此代码,以便在clang和GCC上成功编译?或者,有没有更合适的方法来定义这样的函数?您不能在默认参数中使用参数,即使在未赋值的上下文中也是如此(尽管可能应该修改标准以放宽该限制)。不要使用
decltype(*begin)
,而是使用
decltype(*std::declval<T&>())
编辑2:我同意krzaq的观点,最好只添加另一个模板参数。仅通过强制使用
函数(更多详细信息),您就对算法的性能感到非常悲观。只要拿一个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);"
}
添加另一个模板参数Compare
。这使得编译器更容易进行内联。当我在这里的时候,支援哨兵
template<class It, class Sentinel, class Compare=std::less<void>>
void foo(It begin, Sentinel end, Compare cmp={}) {
}
模板
void foo(它开始,哨兵结束,比较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<>) {
}
模板
使用比较器_sig=bool(T常数&,T常数&);
模板
使用comparator=std::function;
模板
在比较器中使用compare\u<
typename std::迭代器特征::值类型
>;
模板
void foo(T begin,T end,compare_inside_it compare=less){
}
在C++11中,我会编写自己的less
:
struct compare\u less{
模板
布尔运算符(){
返回std::less{}(lhs,rhs);
}
};
并且做:
template<typename T>
void foo(T begin, T end, compare_inside_it<T> compare = compare_less{}) {
}
模板
void foo(T begin,T end,compare_in_it compare=compare_less{}){
}
甚至只是做:
template<typename T>
void foo(T begin, T end, compare_inside_it<T> compare = {}) {
if (!compare) compare=compare_less{};
}
模板
void foo(T begin,T end,compare_in_it compare={}){
如果(!compare)compare=compare_less{};
}
为什么不想为此使用额外的模板参数?出于好奇,您使用函数在哪些方面对性能感到悲观?@krzaq谢谢!如果我对最佳性能感兴趣,我应该选择哪种解决方案?@0x1337我会在不受太多干扰的情况下传递模板参数。它会产生稍差的错误消息(希望能用概念来修复),但可读性好,速度快,与标准库一致。看看Compare
是怎么做的,我会用{}
而不是Compare{}
跟着DRY。
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{};
}