簡體   English   中英

我在與模板參數有關的問題

[英]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()); 但這相當笨拙。 更好的選擇是在模板聲明中交換RandomIteratorT的順序,以便您可以僅指定返回類型: 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()); -如果需要,請加一個參考。

算法細化

be必須是隨機訪問迭代器,因為您正在調用std::sort 但是,計數計算效率很低。 考慮簡單地使用auto count = e - b; auto mid = count / 2; 使用auto將為您提供正確的difference_type,它並不總是與int相同。 通常它是ptrdiff_t,但是即使如此,良好的迭代器代碼也不應假定。 如果不能使用autotypename 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.

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