2015-12-15 2 views
3

Je suis assez nouveau en C++ et j'essaie d'imprimer un vecteur d'Institutions, qui est un type d'objet que j'ai créé. La création de l'objet et le reste de mon programme s'exécutent très bien mais quand j'essaie d'imprimer le vecteur, le "< <" donne une erreur qui dit que "les types d'opérandes sont std :: ostream".Utilisation de std :: ostream pour l'impression de vecteurs

void PrintVector(const vector<Institution> &institutions) 
{ 
    for (int x = 0; x < institutions.size; x++) 
    { 
     cout << institutions.at(x) << endl; 
    } 
} 

J'ai essayé de faire des recherches sur ce que std :: ostream est ou ce qu'elle fait, mais puisque je ne sais pas beaucoup de choses sur C++ (ou la programmation en général), je ne comprends pas l'un des les sites qui l'expliquent. Pourquoi l'habituel "cout < <" ne fonctionnera-t-il pas dans cette situation? Quelqu'un peut-il m'expliquer ce que cela signifie ou s'il y a une façon différente d'imprimer mon vecteur qui ne l'exige pas?

Toute aide est appréciée, merci.

+0

Avez-vous écrit une classe '' opérateur << pour votre 'Institution'? – Chad

+0

Puisque vous savez que les valeurs de 'x' sont des indices valides dans le vecteur, il ne sert à rien de les vérifier à nouveau avec' institutions.at (X) '. Utilisez simplement 'institutions [x]'. Encore mieux, lisez sur les itérateurs. –

Répondre

4

Vous pouvez surcharger l'opérateur ostream (< <) pour votre institution de classe: https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx

ostream& operator<<(ostream& os, const Institution& inst) 
{ 
    os << inst.foo; /* some member variable */; 
    return os; 
} 
+0

Ok, donc où il est dit inst.foo, suis-je censé mettre un des membres dans l'objet inst? –

+2

@ LiliaO.Oui, vous mettriez tous les membres que vous souhaitez imprimer – Tas

+1

@Tas Si je voulais imprimer plusieurs membres, est-ce que je le ferais comme ça? 'os << inst.x << inst.y << inst.z;' –

1

Vous devez fournir un operator << pour votre classe:

std::ostream& operator << (std::ostream& os, const Institution& institution) 
{ 
    os << institution.getValue(); 
    // ... 
    return os; 
} 
1

operator<< est surchargée pour permettre la sortie des types intégrés comme int et double. Mais vous devez dire au compilateur comment la sortie de votre classe Institution par une surcharge encore:

std::ostream& operator<<(std::ostream& os, const Institution& inst) { 
    os << inst.name(); // or something 
    return os; 
} 
+1

Man la compétition est dure T.T –

0

Il y a au moins deux problèmes avec le code que vous avez montré.

1)

for (int x = 0; x < institutions.size; x++) 

std :: vector :: size() est une méthode de classe, une fonction. Ce n'est pas un membre de la classe. Cela devrait lire:

for (int x = 0; x < institutions.size(); x++) 

2)

cout << institutions.at(x) << endl; 

Malheureusement, std::ostream ne sait rien au sujet de votre classe Institution. Vous devrez implémenter une méthode de classe, telle que display(), qui assemblera une représentation imprimable du contenu de la classe et l'écrira dans le flux de sortie. Ainsi, par exemple, si la classe contient deux std::string s, appelé name et address:

class Institution { 

// ... 

public: 

     void display(std::ostream &o) 
     { 
      o << name << std::endl << address << std::endl; 
     } 
// ... 
}; 

... ou, quel que soit le style de mise en forme que vous voulez les instances de classe à afficher.Puis:

for (int x = 0; x < institutions.size(); x++) 
    institutions.at(x).display(std::cout); 

3)

Eh bien, voici un problème de bonus avec votre code. Il est en fait écrit dans un dialecte C++ obsolète qui s'est démodé il y a des décennies. Quel que soit le manuel que vous utilisiez pour apprendre le C++, vous devez l'abandonner, et prendre un manuel qui a été écrit ce siècle, et qui vous apprendra le C++ moderne. En C++ moderne, cela devient beaucoup plus lisible:

for (const auto &institution:institutions) 
    institution.display(std::cout); 
0

Les réponses sont toutes correctes. Je vais fournir une réponse légèrement différente au problème d'affichage, car il s'agit d'un problème récurrent. Ce que vous pouvez faire est de définir une classe abstraite, nous l'appellerons IDisplay, qui déclare une fonction virtuelle pure std::ostream& display(std::ostream&) const et déclare operator<< comme ami. Ensuite, chaque classe que vous voulez afficher peut hériter de IDisplay et implémenter par conséquent la fonction membre display. Cette approche réutilise le code et est assez élégante. Exemple ci-dessous:

#include <iostream> 

class IDisplay 
{ 
private: 
    /** 
    * \brief Must be overridden by all derived classes 
    * 
    * The actual stream extraction processing is performed by the overriden 
    * member function in the derived class. This function is automatically 
    * invoked by friend inline std::ostream& operator<<(std::ostream& os, 
    * const IDisplay& rhs). 
    */ 
    virtual std::ostream& display(std::ostream& os) const = 0; 

public: 
    /** 
    * \brief Default virtual destructor 
    */ 
    virtual ~IDisplay() = default; 

    /** 
    * \brief Overloads the extraction operator 
    * 
    * Delegates the work to the virtual function IDisplay::display() 
    */ 
    friend inline 
    std::ostream& operator<<(std::ostream& os, const IDisplay& rhs) 
    { 
     return rhs.display(os); 
    } 
}; /* class IDisplay */ 

class Foo: public IDisplay 
{ 
public: 
    std::ostream& display(std::ostream& os) const override 
    { 
     return os << "Foo"; 
    } 
}; 

class Bar: public IDisplay 
{ 
public: 
    std::ostream& display(std::ostream& os) const override 
    { 
     return os << "Bar"; 
    } 
}; 

int main() 
{ 
    Foo foo; 
    Bar bar; 
    std::cout << foo << " " << bar;  
} 

Live on Coliru