Search code examples
c++stdstdvectorcoutstd-pair

C++" no match for operator<<" when printing a std::vector<std::pair>


I want to print the vector dicVec in order to check if everything is as I want. But I can´t. I already looked it up, but nothing helped.

This is my current code:

void Translate::read(){
    int i = 0;

    std::ifstream dic("ende.dic");
    if (dic.is_open())
    {
        std::string dicLine;
        while (std::getline(dic, dicLine)){
            std::vector<std::pair<std::string, std::string>> dicVec;
            std::pair<std::string, std::string> dicPair;
            std::size_t pos = dicLine.find(";");
            dicPair.first = dicLine.substr(0, pos);
            //std::cout << dicPair.first << " : ";
            dicPair.second= dicLine.substr(pos+1);
            //std::cout << dicPair.second << std::endl;
            std::cout << dicVec[i];
            i++;
        }
    }
    else {
        throw std::runtime_error("File could not be opened");
    }
}

I also tried to print it using this:

std::cout << dicVec.at(i);

and this:

for (auto i = dicVec.begin(); i != dicVec.end(); ++i)
    std::cout << *i << ' ';

But there´s always this error:

no match for operator<<

What do I have to do in order to print my vector? Thank you for your help.


Solution

  • You are trying to print out a std::pair, but there is no standard operator<< implemented for std::pair, so you will have to write you own.

    Even if you fix that, your code will still fail, because dicVec is empty when you call std::cout << dicVec[i]; You are not adding dicPair to dicVec before printing the contents of dicVec. In fact, dicVec should be declared above the loop, not inside of it.

    Try something more like this:

    typedef std::pair<std::string, std::string> stringPair;
    typedef std::vector<stringPair> stringPairVec;
    
    std::ostream& operator<<(std::ostream &out, const stringPair &p) {
        out << p.first << " : " << p.second << "\n";
        return out;
    }
    
    std:ostream& operator<<(std::ostream &out, const stringPairVec &vec) {
        for (size_t i = 0; i < vec.size(); ++i) {
            out << vec[i];
        }
        return out;
    }
    
    void Translate::read(){
    
        std::ifstream dic("ende.dic");
        if (!dic.is_open()) {
            throw std::runtime_error("File could not be opened");
        }
    
        stringPairVec dicVec;
        std::string dicLine;
    
        while (std::getline(dic, dicLine)) {
            std::size_t pos = dicLine.find(";");
            stringPair dicPair = std::make_pair(
                dicLine.substr(0, pos),
                dicLine.substr(pos+1)
            );
            dicVec.push_back(dicPair);
        }
    
        std::cout << dicVec;
    }
    

    Or, in C++11 and later, you can do this instead:

    using stringPair = std::pair<std::string, std::string>;
    using stringPairVec = std::vector<stringPair>;
    
    std::ostream& operator<<(std::ostream &out, const stringPair &p) {
        out << p.first << " : " << p.second << "\n";
        return out;
    }
    
    std:ostream& operator<<(std::ostream &out, const stringPairVec &vec) {
        for (const auto &p : vec) {
            out << p;
        }
        return out;
    }
    
    void Translate::read(){
    
        std::ifstream dic("ende.dic");
        if (!dic.is_open()) {
            throw std::runtime_error("File could not be opened");
        }
    
        stringPairVec dicVec;
        std::string dicLine;
    
        while (std::getline(dic, dicLine)) {
            std::size_t pos = dicLine.find(";");
            dicVec.emplace_back(
                dicLine.substr(0, pos),
                dicLine.substr(pos+1)
            );
        }
    
        std::cout << dicVec;
    }