Перегрузка << Оператор для печати элемента векторных данных - PullRequest
0 голосов
/ 12 марта 2019

Я создал класс с закрытым вектором, который использует std :: string в качестве типа данных.

#pragma once
#include <string>
#include <vector>
#include <iostream>

class Pokemon {
public:
//Constructor - leaving it here for reference
Pokemon(std::string name, int LVL, int HP, int ATK, int DEF, int SPATK, int SPDEF, int SPD, 
std::vector<std::string>moves, std::vector<int>PP);
//Member Functions
std::vector<std::string> getMoves();
private:
std::vector<std::string>moves;
};   

Чтобы извлечь информацию из этого вектора, я создал общедоступную функцию класса под названием getMoves (), которая должна возвращать всю информацию из этого вектора. Вот определение функции, которое я написал в .cpp файле.

std::vector<std::string> Pokemon::getMoves() {
    return moves;
}

После попытки распечатать вектор с этими движениями с помощью std :: cout и получения ошибки «Нет соответствия для оператора», я понял, что мне пришлось перегрузить оператор <<. </p>

У меня есть несколько вопросов о том, как перегрузить оператор <<, чтобы мой вектор печатался. </p>

  1. Я не уверен, где объявить оператор перегрузки. Я объявляю это перед моим классом? Внутри моего класса в качестве публичной функции друга? В другом заголовочном файле? Внутри моей основной функции?
  2. Какой тип я должен перегружать для печати? Я считаю, что это будет тот же тип, что и мой класс, потому что функция getMoves () принадлежит классу Pokemon, но я не уверен, что это так или std::vector<std::string>
    1. Как использовать этот перегруженный оператор в моей основной функции? Как обычный std :: cout?

Буду признателен за любую помощь с этими вопросами, спасибо!

Ответы [ 2 ]

0 голосов
/ 12 марта 2019
#include <iostream>
#include <vector>
#include <map>

// Helper Function to Print Test Containers (Vector and Map)
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U>& p) {
    out << "[" << p.first << ", " << p.second << "]";
    return out;
} 

template <template <typename, typename...> class ContainerType, typename 
ValueType, typename... Args>
void print_container(const ContainerType<ValueType, Args...>& c) {
    for (const auto& v : c) {
        std::cout << v << ' ';
    }
    std::cout << '\n';
}

Как упомянул NutCracker, перегрузка operator << - ваш лучший друг практически во всех типах контейнеров.В дополнение к его хорошему ответу, здесь есть немного расширенная версия шаблонного разрешения для печати всех типов контейнеров STL.

В основном перегрузка для парного типа контейнеров в дополнение к векторам.В качестве примера.ValueType -> First or only Element in container template и Args... variadic template as rest of the elements in container (второй или более элементов) Для pair <T,U> basic map-unordered_map у вас есть только первый и второй элементы для overload Вы можете применить эту технику почти ко всем типам контейнеров.Если вы просто хотите распечатать все функции Pokemon без вызова какой-либо дополнительной функции pokemon::getMoves(), вы можете overload << for pokemon class, а также, возможно, было бы лучше напечатать только 1 покемона и т. Д.

friend, чтобы предоставить доступ к приватным иоткрытые участники

friend ostream& operator<< (ostream& os, const Pokemon& pokemonobj) {
    os << print_container(pokemonobj.getMoves());
    return os;
}
0 голосов
/ 12 марта 2019

Следующий пример перегрузит оператор << для каждого вектора. Если вы хотите указать выходные данные для вашего конкретного вектора, то создайте оболочку структуры или класса.

#include <iostream> 
#include <vector>

using namespace std; 

template <typename T> 
ostream& operator<<(ostream& os, const vector<T>& v) 
{ 
    os << "[";
    for (int i = 0; i < v.size(); ++i) { 
        os << v[i]; 
        if (i != v.size() - 1) 
            os << ", "; 
    }
    os << "]\n";
    return os; 
}

Теперь, когда вы хотите напечатать вектор следующим образом:

int main() {
    vector<int> a = {0, 1, 2};
    cout << a << endl;
}

будет напечатан следующий результат: [0, 1, 2]

...