Naz-Al Islam
Naz-Al Islam

Reputation: 11

How to fix "no instance of overloaded function" in vector push_back?

I want to write a function which takes as input a pointer to a vector pointer which point to a string (Dictionary) and a pointer which points to a char (p). The function will check if the char is in the Dictionary and if it isn't there it adds the p in the vector Dictionary.

My code:

#include <iostream>
#include <string>
#include <vector>
using std::string;
using std::vector;

std::vector<string *> dictionary;

void manageDictionary(vector<string *> * dictionary, char *p) {
    for (unsigned int i = 0; i < (*dictionary).size(); i++) {
        string * pstring = (*dictionary).at(i);
        if ((*pstring).compare(p)) {
            (*dictionary).push_back(p);
        }
    }
}

However, the visual studio compiler shows I have an error in the if statement just before the push_back method (.). When I hover on the error, it says "no instance of overloaded function".

I added the std::vector<string *> dictionary; at the beginning, still cannot figure out where the problem is.

Upvotes: 0

Views: 5633

Answers (1)

Fran&#231;ois Andrieux
Fran&#231;ois Andrieux

Reputation: 29023

dictionnary is a vector of std::string*. std::string* and char* are totally unrelated types. To convert from char* to std::string* will require you to create a new string that contains the value of p for your dictionnary, rather than passing a char* directly. This change will allow your example to compile, but the resulting function is error prone.

#include <string>
#include <vector>
using std::string;
using std::vector;

void manageDictionnary(vector<string *> * dictionnary, char *p) {
    for (unsigned int i = 0; i < (*dictionnary).size(); i++) {
        string * pstring = (*dictionnary).at(i);
        if ((*pstring).compare(p)) {
            (*dictionnary).push_back(new string(p));
            // Make a new string     ^^^^^^^^^^
        }
    }
}

This solution will require you to delete your strings manually which is not the way things are done in c++. Changing from std::vector<std::string*> to simply std::vector<std::string> will solve this problem, and avoid you headaches in the future. There are other unnecessary pointers that can be removed. Since at(i) returns a string& then we should change pstring to string&. Since dictionnary is not optional (can't be nullptr) and always points to the same vector we can also change it to a vector<string>&.

void manageDictionnary(vector<string> & dictionnary, char *p) {
    for (unsigned int i = 0; i < dictionnary.size(); i++) {
        string & pstring = dictionnary.at(i);
        if (pstring.compare(p)) {
            dictionnary.push_back(p);
        }
    }
}

This latest version will work fine and is much more in line with c++'s philosophy for resource management. I recommend you read on a few topics :

Additionally, consider using std::set<string> or std::unordered_set<string> for a more convenient representation of a dictionnary.

In the future, note that the preferred way to access a pointer's methods is ptr->foo() rather than (*ptr).foo().

Upvotes: 1

Related Questions