簡體   English   中英

從模板函數中的解引用迭代器推斷類型

[英]Inferring a type from a dereferenced iterator in a template function

我正在通過“ Accelerated C ++”中的練習進行練習,並且發現了一些我不了解的有關編譯器如何推斷函數模板中類型的行為。 在練習10-2中,要求我們編寫一個模板函數,該函數可以計算向量或內置數組中算術類型列表的中位數。 我偶然發現了一個解決此問題的示例解決方案,該解決方案涉及一個模板函數,該函數計算並返回兩個迭代器之間的容器中值,即,我創建了以下文件“ median.hpp”:

#ifndef median_hpp
#define median_hpp

#include <algorithm>
#include <stdexcept>
#include <vector>

using std::domain_error;
using std::sort;
using std::vector;

template <class T, class Iterator>
T median(Iterator begin, Iterator end) {

  //check if the container is empty
  if (begin == end)
    throw domain_error("median of an empty container");

  //create a vector with the same type as the container
  //and copy the container contents into it 
  vector<T> temp;

  for ( ; begin != end; ++begin)
    temp.push_back(*begin);

  //sort the temporary vector, and compute and return the median
  sort(temp.begin(), temp.end());

  size_t mid = temp.size() / 2;

  T ret = (temp.size() % 2 == 0)
    ? (temp[mid] + temp[mid - 1]) / 2
    : temp[mid];

  return ret;
}

#endif /* median_hpp */

因此,如果我想計算一個數組和向量的中值,以證明此函數適用於兩種容器類型,則可以使用上述模板函數,如下所示:

#include <iostream>
#include <vector>
#include "median.hpp"

using std::vector;
using std::cout;
using std::cin;
using std::endl;

int main()
{

    int arr[] = {12,2,4,1,4,56,1};

    const size_t nData = sizeof(arr)/sizeof(*arr);
    vector<double> v(arr, arr + nData);

    cout << median(v.begin(),v.end()) << endl;
    cout << median(arr, arr + nData) << endl;

    return 0;
}

但是,由於我不明白的原因,出現以下錯誤:

沒有匹配的函數來調用'median'...候選模板被忽略:無法推斷模板參數'T'

據我所知,問題在於編譯器無法從解引用的迭代器中推斷“ T”的類型。 我想知道

答:為什么會這樣?

B.是否有解決此問題的優雅方法?

編譯器可以推斷Iterator ,但不能推斷T 這是因為otator無法說出如何根據傳遞給T的任何內容來推斷T Iterator 從未知的Iterator類型,您將如何在不知道Iterator實際上是什么的情況下知道T是什么? 編譯器根本不知道這一點。

但是,由於您知道Iterator是實際的迭代器類型,並且大多數迭代器都將類型別名恢復為所包含的類型T您可以執行以下操作

template <class Iterator, class T = typename std::iterator_traits<Iterator>::value_type>
T median(Iterator begin, Iterator end) { ... }

可以從例如std::vector參考中收集有關所有這些信息,該參考告訴您std::vector中的iterator類型是隨機訪問迭代器 ,其中提及value_type以及如何從std::iterator_traits找到它。

std::iterator_traits應該可以用於所有標准迭代器,而不只是std::vector給出的隨機訪問迭代器。

由於median沒有類型T參數,因此編譯器無法推斷該類型。

解:

template <class Iterator, class T = typename std::iterator_traits<Iterator>::value_type>
T median(Iterator begin, Iterator end) {
    // ....
}

現場例子

暫無
暫無

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

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