【问题标题】:no matching function call for selection sort function with templates(C++)没有匹配的函数调用模板选择排序函数(C++)
【发布时间】:2013-01-19 09:15:21
【问题描述】:

我在玩模板,我想知道为什么我在使用模板时会出现不匹配的函数错误。

/*selection sort*/
template <typename InputIterator, typename T>
void selection_sort(InputIterator first, InputIterator last){
    InputIterator min;
    for(; first != last - 1; ++first){
        min = first;

        for(T i = (first + 1); i != last ; ++i)
        {
            if(*first < *min)
                min = i;
        }
        myswap(*first, *min);
    }
}

int main(){
    int a[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    vector<int> v(a, a+10);
    selection_sort(v.begin(),v.end());
}

【问题讨论】:

  • 另请注意,如果您使用的是 C++11,则无需将其复制到向量中;只需使用您标记的答案(rhalbersma's)并使用std::begin(a)std::end(a) 作为第一个和最后一个迭代器。其余的会自己处理。

标签: c++ sorting templates selection template-argument-deduction


【解决方案1】:

你有一个未推导出的模板参数 T,所以你需要 1) 移动你的 typename T 作为第一个模板参数:

// now InputIterator will be deduced
template <typename T, typename InputIterator>
void selection_sort(InputIterator first, InputIterator last)
{
    // your implementation
}

和 2) 将您的呼叫限定为selection_sort&lt;int&gt;(v.begin(), v.end());

顺便说一句,这里有一个更通用的选择排序实现,注意它只需要一个迭代器和比较函数作为模板参数,比较函数采用迭代器指向的值类型(这是 C++11 代码,因为默认函数模板参数,对于 C++98 编译器,你需要有 2 个重载,带或不带比较函数)

template< typename ForwardIterator, typename Compare = std::less<typename std::iterator_traits<ForwardIterator>::value_type> >
void selection_sort(ForwardIterator first, ForwardIterator last, Compare cmp = Compare())
{
        for (auto it = first; it != last; ++it) {
                auto const selection = std::min_element(it, last, cmp);
                std::iter_swap(selection, it);
        }
}

std::min_element 的调用相当于你的for 循环,iter_swap 相当于你自己的swap。使用 STL 算法的优点是它们更可能是正确的(手写代码中的一个错误很常见)

PS:您可以使用std::upper_boundstd::rotateexercise 供读者使用)类似地在两行中编写插入排序算法

【讨论】:

  • +1 表示被称为iterator_traits 的美妙粘液。 喜欢那堂课。
  • @WhozCraig 在写了太多次ForwardIterator::value_type 并试图传递一个常规的指针之后,我也学会了喜欢这个类;-)
【解决方案2】:

问题是 typename T 似乎没有被使用,无法被编译器推导出来。您必须明确指定类型:

selection_sort<vector<int>::iterator, int>(v.begin(),v.end());

【讨论】:

  • 连迭代器类型都推不出来,因为它不是最后一个模板参数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 2013-01-26
  • 2017-09-26
相关资源
最近更新 更多