簡體   English   中英

模板出錯:沒有匹配的函數調用

[英]Error with templates: no matching function call

我正在通過加速C ++工作並且遇到Ex的問題。 10.2問題涉及從前一章重寫中值函數,因此現在可以用向量或內置數組調用中值。 中值函數還應允許任何算術類型的容器。

我無法在下面詳細說明兩次調用中位數 - 我收到錯誤消息

No matching function for call to 'median'

我從一些研究中得知,當使用模板時,應該在編譯時知道Type。 這可能是潛在的問題嗎? 有沒有辦法以某種方式傳遞Type作為模板參數?

到目前為止,這是我的代碼:

#include <iostream>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include <cstddef>

using namespace std;

template <class Iterator, class Type>
Type median(Iterator begin, Iterator end)
{
    vector<Type> vec(begin,end);
    typedef typename vector<Type>::size_type container_sz;
    container_sz size = vec.size();

    if (size == 0) {
        throw domain_error("median of an empty vector");
    }

    sort(vec.begin(), vec.end());

    container_sz mid = size/2;
    return size % 2 ==  0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}

int main()
{
    vector<int> grades;

    for (int i = 0; i != 10; ++i){
        grades.push_back(i);
    }

    const int int_array[] = {2, 9, 4, 6, 15};
    size_t array_size = sizeof(int_array)/sizeof(*int_array);

    cout << median(int_array, int_array + array_size) << endl;   //error here: Semantic Issue, No matching function for call to 'median' 
    cout << median(grades.begin(), grades.end()) << endl;        //error here: Semantic Issue, No matching function for call to 'median' "

    return 0;
}

通常,解決此問題的最佳方法是使用如上所述的iterator_traits 但是,為了回答書中的特定問題10.2(不假設Iterator_trait知識),可以按如下方式進行: - 注意類類型必須首先列出,而不是類Iterator。 此外,必須調用median<int>(grades.begin(), grades.end())而不是中median(grades.begin(), grades.end())

#include <iostream>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include <cstddef>

using namespace std;

template <class Type, class Iterator>       //the order allows the second template parameter type to be deduced (Iterator)                                           
Type median(Iterator begin, Iterator end)   //while requiring you still provide the first type
{

    vector<Type> vec(begin,end);

    //typedef typename vector<Type>::size_type container_sz;
    //container_sz size = vec.size()
    auto size = vec.size();

    if (size == 0) {
        throw domain_error("median of an empty vector");
    }

    sort(vec.begin(), vec.end());

    //container_sz mid = size/2
    auto mid = size/2;

    Type ret = size % 2 ==  0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];

    return ret;
}


int main()
{

    vector<int> grades = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    const int int_array[] = {2, 9, 4, 6, 15};

    size_t array_size = sizeof(int_array)/sizeof(*int_array);

    cout << median<int>(int_array, int_array + array_size) << endl;  //must provide int here, in order to give the template the return type at compile time
    cout << median<int>(grades.begin(), grades.end()) << endl;


return 0;

}

您的錯誤源於對Type的推導,這是所提供的參數無法實現的。 可以使用標准庫類iterator_traits執行此操作,如下所示:

template <
    class Iterator, 
    class Type = typename std::iterator_traits<Iterator>::value_type>
Type median(Iterator begin, Iterator end)
{
    vector<Type> vec(begin,end);

    typedef typename vector<Type>::size_type container_sz;

    container_sz size = vec.size();

    if (size == 0) {
        throw domain_error("median of an empty vector");
    }

    sort(vec.begin(), vec.end());

    container_sz mid = size/2;

    return size % 2 ==  0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}

iterator_traits類解析了提供的迭代器類型,以確定實際迭代的內容(稍微復雜一點,但這是一個不錯的總結)。 有關其工作原理的更多信息,請參閱class iterator_traits的文檔。 它是確定迭代器值類型的最便捷機制。

注意:為確保不會出現默認模板參數Type聲明的意外繞過,您還可以執行以下操作:

template <class Iterator>
typename std::iterator_traits<Iterator>::value_type median(Iterator begin, Iterator end)
{
    if (begin == end)
        throw domain_error("median of an empty vector");

    typedef typename std::iterator_traits<Iterator>::value_type Type;
    std::vector<Type> vec(begin,end);
    sort(vec.begin(), vec.end());

    typename std::vector<Type>::size_type mid = vec.size()/2;
    return vec.size() % 2 ==  0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}

它有點密集,拋出大部分中間的東西,但如果你盯着它足夠長的時間你會理解它是如何工作的,它會減少你的模板參數列表,只使用你真正關心的一件事; Iterator類型,由您提供給函數的參數簡單推導出來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM