Проблема с подписью шаблона - PullRequest
0 голосов
/ 08 февраля 2011

Я новичок в использовании шаблонов и должен использовать шаблон, чтобы что-то делать, но не знаю, как вызвать шаблонную функцию. Наверное, это просто, но я не вижу этого.

template<class It, class T>


// iterator and value_type of *It
void Calc(It begin, It end, std::pair<int, int> &out)
{
        std::vector<It>::iterator iter;
    std::map<int, int> StartMap;
    std::map<int, int>::reverse_iterator rit;

    int sum, start, stop, count;
    start = stop = 1;
    count = sum = 0;

    for(iter = begin; iter != end; iter++ )
    {
        sum += iter;
        count++;
        stop++;
        if(sum <= 0)
        {
            // store original start
            StartMap.insert(start, count);
            // set new start position
            start = stop;
        }   
    }

    // set iterator to highest value
    rit = StartMap.rbegin();

    start = rit->first;
    stop = start + rit->second;

    out.insert(start, stop);
}

но не знаю, как я это называю с помощью двух итераторов std :: vector. Я пробовал это

void doSomething(std::vector<int>& stopsVec)
{
    std::pair<int, int> out;
    Calc<std::vector<int>::iterator, std::pair<int, int>>(stopsVec.begin(), stopsVec.end(), &out);
}

Ответы [ 3 ]

4 голосов
/ 08 февраля 2011
void doSomething(std::vector<int>& stopsVec)
{
    std::pair<int, int> out;
    Calc<std::vector<int>::iterator, std::pair<int, int> >
        (stopsVec.begin(), stopsVec.end(), out);   // not &out
}

Calc принимает ссылку на std::pair<int, int>, поэтому вы хотите просто указать out. Передача &out пытается передать указатель на пару - что не сработает.

EDIT

при условии, что подпись действительно:

template<class It>
void Calc(It begin, It end, std::pair<int, int> &out)

Вы можете позвонить с помощью:

Calc(stopsVec.begin(), stopsVec.end(), out);

Компилятор может определить правильный тип шаблона из параметров, не требуя указывать их между <>

EDIT

Кит делает хорошую точку ниже. Это еще одна ошибка компиляции, которую вы могли бы получить здесь. Также обратите внимание, что:

sum += iter;

не делает то, что вы хотите. Вы, вероятно, имели в виду:

sum += *iter;

Но поскольку sum является целым числом, а iter является типом шаблона, на самом деле это не шаблонный метод общего назначения. Это действительно будет работать только для итераторов над числовыми типами.

И еще одна проблема:

Calc<std::vector<int>::iterator, std::pair<int, int> >  // use a space
    (stopsVec.begin(), stopsVec.end(), out);

вместо

Calc<std::vector<int>::iterator, std::pair<int, int>>  // ">>" is shift operator
    (stopsVec.begin(), stopsVec.end(), out);

Вам нужен пробел между закрывающими > знаками, чтобы иметь синтаксис шаблона. В противном случае вы выполняете битовое смещение (или извлечение потока), и компилятор запутается, потому что с этого момента ничего не будет иметь смысла.

0 голосов
/ 10 февраля 2011

Вам не нужно явно передавать итерируемый тип в качестве аргумента шаблона. Проектировщики STL были достаточно мудры и поняли, что это часто встречается, и есть (не очень красивый, но совершенно правильный) способ проанализировать тип итератора, чтобы получить его базовый тип следующим образом:

typedef typename std::iterator_traits<It>::value_type value_type;

Как только вы это сделаете, вы можете использовать имя value_type для ссылки на тип, который повторяется. Это позволяет переписать функцию шаблона как

template <typename It>
void Calc(It begin, It end, std::pair<int, int>& out) {
     typedef typename std::iterator_traits<It>::value_type value_type;
     /* ... Rest of the code, now using this type ... */
}

И чтобы заключить сделку, теперь, когда не требуется никаких вспомогательных типов, вы можете вызвать функцию напрямую как

std::vector<int> v = /* ... */
std::pair<int, int> result;
Calc(v.begin(), v.end(), result);

Надеюсь, это легче читать и писать!

0 голосов
/ 08 февраля 2011

Обратите внимание:

template<class It, class T>
void Calc(It begin, It end, std::pair<int, int> &out)
{
    std::vector<It>::iterator iter;
    for(iter = begin; iter != end; iter++ )

неправильно. Вероятно, должно быть:

template<class It, class T>
    void Calc(It begin, It end, std::pair<int, int> &out)
    {
        It iter;
        // etc.
        for(iter = begin; iter != end; iter++ )

Но также обратите внимание, что в C ++, как правило, предпочтительнее следовать подходу «объявление является инициализацией», так что это становится:

  template<class It, class T>
        void Calc(It begin, It end, std::pair<int, int> &out)
        {
             // etc.
            for(It iter = begin; iter != end; iter++ )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...