2016-12-02 3 views
1

У меня есть следующие карты:Показать строку, вектор <int> карту в C++

std::map<std::string, std::vector<int> > my_map; 

вставить ключи и значения в моей карте так:

my_map.insert(std::pair<std::string, std::vector<int> >(nom,vect)); 

Как я могу напечатать обе кнопки и значения моей карты?

Я уже опробовали:

for(std::map<std::string, std::vector<int> >::iterator ii=my_map.begin(); ii!=my_map.end(); ++ii) 
    { 
     std::cout << (*ii).first << ": " << (*ii).second << std::endl; 
    } 

Но по какой-то причине я получаю эту ошибку:

error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream<char>’ and ‘std::vector<int>’) 
std::cout << (*ii).first << ": " << (*ii).second << std::endl; 
+0

Как можно напечатать 'std :: vector '? Вы не можете, если вы не определяете, как это должно быть напечатано, предоставляя перегруз для 'operator <<' – user463035818

+0

. Вам нужно будет перебирать «std :: vector », либо делая это на месте, либо перегружая 'operator <<' для этого типа (что я не рекомендую.) – Tobias

+0

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

ответ

3

Прежде всего, используйте typedef (или более современный метод using):

typedef std::vector<int> ivector; 
typedef std::map<std::string,ivector> sivmap; 

sivmap my_map; 

// now benefits of using synonyms 
my_map.insert(sivmap::value_type(nom,vect)); 

// or even easier 
my_map.insert(std::make_pair(nom,vect)); 

// for loop is less verbose as well 
// when there is no intention to modify data use const_iterator 
for(sivmap::const_iterator ii=my_map.begin(); ii!=my_map.end(); ++ii) 
{ 
    std::cout << ii->first << ": " << ii->second << std::endl; 
} 

теперь для вашего цикла, чтобы работать создать оператор

std::ostream &<<(std::ostream &out, const ivector &iv) 
{ 
    out << '['; 
    for(ivector::const_iterator it = iv.begin(); it != iv.end(); ++it) { 
     if(it != iv.begin()) out << ", "; 
     out << *it; 
    } 
    return out << ']'; 
} 

Это позволит не только сделать код короче и компактнее, но менее подвержены ошибкам и легче читать и изменять

+0

Я не большой поклонник определения оператора вывода для 'use' typedef. Он отправляет ложное сообщение о его определении для отдельного типа, когда это просто псевдоним. С этим столкнулась бы другая выходная процедура с другим псевдонимом. –

+0

@TheVee Это просто пример, его можно легко изменить на шаблон, который будет работать с любым вектором, я просто не хотел бы толкать, чтобы сразу сопоставлять информацию с OP. – Slava

2

Ну, это потому, что нет operator<< для std::vector<int>, что делает его одним из более редкие виды компиляции C++, которые достаточно понятны и кратки. Точно так же, как вы написали свой собственный вывод для std::map с использованием итератора, вам нужно будет сделать что-то подобное для std::vector.

Одна из причин, почему стандарт не делает это для нас является беспредельным многообразием форматов, что люди могут ожидать выхода появиться. Например, если вы хотите, чтобы данные, окруженный ( и ) и каждый из двух элементов разделенном , и пространством, проще спросить вас, как пользователь реализовать это в нескольких строках, чем создать алгоритм, который позволяет это, но также печатать каждый элемент на отдельной строке с выравниванием в десятичной точке и с отступом для рекурсивная печать векторов векторов, которые кто-то может захотеть.

По этой же причине рекомендуется форматировать вектор в том месте, где оно вам нужно, а не на самом деле, и operator<<. Если вы собираетесь использовать один и тот же механизм печати для одного и того же вектора в нескольких точках вашей программы и хотите иметь возможность писать его красиво, как std::cout << vector << '\n', лучший способ - создать класс, публично распространяющий std::vector<int>, как в

class printable_vector : public std::vector<int> { 

    using std::vector<int>::vector; // inherit constructors 
    // (all other public member functions are inherited automatically) 

    friend std::ostream& operator<< (std::ostream& os, const printable_vector& vector) { 
    // do the actual printing to os... 
    return os; 
    } 
}; 

Таким образом, вы можете управлять printable_vector в любом случае вы могли нормально std::vector<int>, но он также предлагает функциональные возможности вывода.

1

Вам нужно добавить еще один для bucle, чтобы решить эту проблему:

#include <map> 
#include <vector> 
#include <iostream> 
#include <string> 

using namespace std; 

int main() 
{ 
    std::map<std::string, std::vector<int> > my_map; 

    string nom = "carlitos"; 
    vector<int> vect; 

    vect.push_back(1); 
    vect.push_back(2); 
    vect.push_back(3); 
    vect.push_back(4); 


    my_map.insert(std::pair<std::string, std::vector<int> >(nom,vect)); 

    for(std::map<std::string, std::vector<int> >::iterator ii=my_map.begin(); ii!=my_map.end(); ++ii) 
    { 
    for(std::vector<int>::iterator iii=(*ii).second.begin(); iii!=(*ii).second.end(); ++iii) 
    { 
     std::cout << (*ii).first << ": " << *iii << std::endl; 
    } 
    } 
} 

Test!

(это потому, что std::cout не будет печатать std::vector непосредственно через оператора <<)

Смежные вопросы