Как сделать параметр вектора с неспецифическим типом? - PullRequest
0 голосов
/ 30 июня 2019

Я стремлюсь создать функцию C ++, которая принимает параметр вектора и, независимо от типа, заданного для вектора, выводит содержимое вектора по одному, рядом друг с другом.Приведенный ниже код работает для векторов типа <int>:

#include <iostream>
#include <vector>

using std::vector;

void PrintVect(vector <int> vect) {
    for (unsigned i = 0; i < vect.size(); i++) {
        std::cout << vect[i];
    }
}

int main() {

    vector <int> nums = {1, 2, 3};

    PrintVect(nums);
}

Какие изменения я должен внести, чтобы он работал с любым типом вектора?

Ответы [ 3 ]

7 голосов
/ 30 июня 2019

Просто: сделайте это функцией шаблона.Также вы должны передавать вектор по (const) ссылке, чтобы избежать ненужных копий.

template<typename T, typename Allocator>
void PrintVect(const std::vector<T, Allocator> &vect)
{
    for (const auto &i : vect) std::cout << i;
}
2 голосов
/ 30 июня 2019

Вы можете создать шаблонную функцию, которая фактически создаст копию функции для каждого vector<type>, который вы используете с ней.

#include <iostream>
#include <vector>

// take the vector by reference to not copy the whole vector
// make it const to promise to not change the vector
template<typename T>
void PrintVect(const std::vector<T>& vect) {
    for(const auto& val : vect)
        std::cout << val;
}

int main() {
    std::vector<int> nums = {1, 2, 3};

    PrintVect(nums);
}

Чтобы сделать его еще проще в использовании, вы можете превратить свою функцию в перегрузку для operator<<:

#include <iostream>
#include <vector>

template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vect) {
    for(const auto& val : vect)
        os << val;
    return os;
}

int main() {
    std::vector<int> nums = {1, 2, 3};

    std::cout << nums << "\n";
}
2 голосов
/ 30 июня 2019

vector<int> и векторы с другим типом элемента, например, vector<string>, имеют разные типы и не имеют общего "супертипа", который вы можете передать своей "функции печати всех видов векторов".

Однако вы можете определить функцию шаблона, которая принимает тип элемента вектора в качестве параметра шаблона; при этом компилятор автоматически сгенерирует выделенную функцию печати для каждого типа элемента, который вы фактически используете:

template <typename T>
void PrintVect(const vector <T> &vect) {
    for (auto val : vect) {
        std::cout << val << " ";
    }
    std::cout << endl;
}

int main() {

    vector <int> nums = {1, 2, 3};
    PrintVect(nums);

    vector <string> strings = { "one", "two", "three" };
    PrintVect(strings);
}

Обратите внимание на const и & в void PrintVect(const vector <T> &vect); поскольку вектор не изменен, передача копии вектора была бы излишней; таким образом, тип параметра должен быть константной ссылкой, то есть const &.

...