шаблон вектор

Я пытаюсь реализовать функцию, которая позволяет мне сделать такой вызов

// veca is a vector of tuples in my case
columnViewOfTuple<0>(veca);

Я реализовал такую ​​функцию следующим образом

template<int N>
struct myfunction {
    template<typename T, typename R>
    std::vector<R> operator() (T& container)
    {
        std::vector<R> myvector;
        for(typename T::iterator it = container.begin(); it!=container.end(); it++)
            myvector.push_back((R)(*it).template get<N>());
        return myvector;
    }
};

всякий раз, когда я вызываю myfunction‹0>(vec5), где vec5 — некоторый вектор кортежей, он говорит

main.cpp: в функции 'int main()': main.cpp:156: ошибка: конфликтующее объявление 'myfunction‹0> vec5' main.cpp:155: ошибка: 'vec5' имеет предыдущее объявление как 'main() ::vec1_t vec5'

Ребята, вы знаете, как это исправить?

Спасибо


person Bob    schedule 01.10.2010    source источник
comment
Почему вы хотите, чтобы int N был параметром шаблона, а не параметром функции?   -  person JoshD    schedule 02.10.2010
comment
См., например: stackoverflow.com/questions/1600464   -  person CB Bailey    schedule 02.10.2010
comment
это требование. Мне нужно N как параметр шаблона   -  person Bob    schedule 02.10.2010
comment
Обычно вам нужно myfunction<0>()(vec5);: myfunction - это не функция, это класс: вы должны создать его экземпляр, прежде чем вы сможете вызвать operator(). Но я не уверен, что это сработает, потому что я не пробовал. Я не думаю, что параметр шаблона R можно вывести, поэтому на самом деле вам нужно myfunction<0>().operator()<R>(vec5);, где R заменен типом значения vec5.   -  person Steve Jessop    schedule 02.10.2010


Ответы (2)


Петля должна быть

    for(typename T::iterator it = container.begin(); it!=container.end(); it++)
        myvector.push_back((R)(*it).template get<N>());

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

typename используется, чтобы сообщить компилятору, что определенное полное имя предназначено для обозначения типа, а не значения (функция/статический элемент данных/и т. д.).

Вторая проблема, которая решается добавлением template, аналогична. Он сообщает компилятору, что get является шаблоном и, таким образом, <N является не сравнением с N, а началом списка аргументов шаблона.

person Johannes Schaub - litb    schedule 01.10.2010
comment
+1 за эту часть шаблона (и в целом хороший ответ). К сожалению, я сам этого не знал. - person JoshD; 02.10.2010

Вам нужно использовать typename перед T::iterator. Так сказать typename T::iterator.

Редактировать1, включая template, как указано Йоханнесом, чтобы предотвратить дезинформацию.

Итак, ваш код должен быть таким:

template<int N>
struct myfunction {
    template<typename T, typename R>
    std::vector<R> operator() (T& container)
    {
        std::vector<R> myvector;
        for(typename T::iterator it = container.begin(); it!=container.end(); it++)
            myvector.push_back((R)(*it).template get<N>());
        return myvector;
    }
};
person JoshD    schedule 01.10.2010
comment
спасибо, это было полезно. Однако я попытался использовать функцию - person Bob; 02.10.2010