[英]I'm having problems relating to template arguments
template <class RandomIterator, class T>
T median(RandomIterator b, RandomIterator e)
{
std::sort(b, e);
int count = 0;
for(RandomIterator ri = b; ri != e; ++ri)
++count;
int mid = count / 2;
return (count % 2 == 0) ? *(b+mid) : (*(b+mid) + *(b+mid+1)) / 2;
}
我在T類(中位數函數的返回類型)上遇到麻煩。 如果我將其取出並將T轉換為int,它似乎可以工作,但會減少使用模板的含義。 救命!
切換模板參數的順序:
template <class T, class RandomIterator>
T median(RandomIterator b, RandomIterator e)
這樣,您只需在通話時傳遞T類型:
median<int>(it1, it2);
或者,更好的是,完全擺脫T:
template <class RandomIterator>
auto median(RandomIterator b, RandomIterator e) -> auto(*b)
為了回答您的實際問題,模板的問題是編譯器需要能夠僅從函數調用中找出類型T
是什么。 它之所以不能這樣做,是因為T
從不直接使用,當然也不在函數簽名(不包括返回類型)中使用。
一種方法是在調用時顯式聲明它,例如median<std::vector<double>::iterator, double>(mvvec.begin(), myvec.end());
但這相當笨拙。 更好的選擇是在模板聲明中交換RandomIterator
和T
的順序,以便您可以僅指定返回類型: median<double>(myvec.begin(), myvec.end());
但是,在C ++ 11和更高版本中,您可以做得更好。 將class T
放到模板中,並使用auto,並在需要時指定迭代器的value_type: auto median(RandomIterator b, RandomIterator e) -> decltype(*b)
您可能會發現decltype不必要。 但是,您還需要確定是否要返回一個值或一個引用-每種方法都有優缺點,所以我無法為您決定。
但是,您的函數與眾不同之處在於,它們都在一個范圍(一對迭代器)上運行,但返回一個值。 大多數STL算法都返回一個迭代器,因為它們不確定取消引用是否安全。 例如,假設您從一個空向量傳遞了begin()和end()。 通過返回迭代器,調用者可以決定取消引用。 這也解決了返回值或引用的問題。 然后,該調用只是median(mvvec.begin(), myvec.end());
-如果需要,請加一個參考。
b
和e
必須是隨機訪問迭代器,因為您正在調用std::sort
。 但是,計數計算效率很低。 考慮簡單地使用auto count = e - b;
auto mid = count / 2;
使用auto
將為您提供正確的difference_type,它並不總是與int相同。 通常它是ptrdiff_t,但是即使如此,良好的迭代器代碼也不應假定。 如果不能使用auto
則typename std::iterator_traits<RandomIterator>::difference_type
是正確的類型。
無需將返回類型指定為模板參數。 您可以使用以下方法訪問迭代器的基礎類型:
std::iterator_traits<RandomIterator>::value_type
如果仍然要這樣做,則必須顯式指定所有模板參數的類型,因為編譯器無法通過使用提供的其他類型來唯一地推斷出它。
我將其完全刪除,如下所示:
template <class RandomIterator>
std::iterator_traits<RandomIterator>::value_type median(RandomIterator b, RandomIterator e)
甚至更好地使用自動
template <class RandomIterator>
auto median(RandomIterator b, RandomIterator e)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.