Search code examples
c++listconstructorstlstd-pair

C++ List of Pairs


While getting comfortable with the C++ STL I ran into this issue using a list of pair objects.

int count (std::string input, std::vector<std::string> screen){

  std::string::iterator it = input.begin();

  std::pair<std::string, int> freq[10];
  std::list<std::pair<std::string,int>  > freq2;

  freq2.push_back(std::make_pair(*it,0)); //ERR:No instance of fn matches arg list 
  freq2.push_back(std::make_pair('S',0)); //ERR:No instance of fn matches arg list
  freq2.push_back(std::make_pair("S",0)); //This is fine

  freq[0] = std::make_pair(*it,0);        //This is fine
  freq[0] = std::make_pair("S",0);        //This is fine
  freq[0] = std::make_pair('S',0);        //This is fine

  return 1;

}

Both freq and freq2 are quite similar except freq2 is just a list. Freq is able to accept chars, strings, and the iterator pointer and both pairs (freq,freq2) are declared as pairs. Not sure why this is happening, any tips? Thanks.

edit: It makes a lot more sense now, all the responses I got were really helpful, thank you guys!


Solution

  • Class std::basic_string has no constructor that has one parameter of type char.So these statemenets are invalid

      freq2.push_back(std::make_pair(*it,0)); //ERR:No instance of fn matches arg list 
      freq2.push_back(std::make_pair('S',0)); //ERR:No instance of fn matches arg list
    

    Speaking more precisely in these statements there is an attempt to build an object of type std::pair<std::string, int> from an object of type std::pair<char, int>. This requires that there would be a constructor of class std::string that has parameter of type char. However there is no such a constructor.

    As for these statements

      freq[0] = std::make_pair(*it,0);        //This is fine
      freq[0] = std::make_pair('S',0);        //This is fine
    

    then there is used an assignment operator of class std::basic_string. The class has an overloaded assignment operator that accepts an object of type char.

    basic_string& operator=(charT c);
    

    So these statements are correct.

    Consider the following example

    #include <iostream>
    #include <string>
    #include <utility>
    
    int main() 
    {
        std::pair<std::string, int> p1 = { "a", 1 };
        std::pair<char, int> p2 = { 'B', 2 };
    
        p1 = p2;
    
        std::cout << p1.first << '\t' << p1.second << std::endl;
    
        return 0;
    }
    

    The output is

    B   2
    

    As class std::pair has a template assignment operator and class std::string in turn has assignment operator that has parameter of type char then this code is compiled successfully.

    If you would write for example

    std::pair<std::string, int> p1 = std::make_pair( 'a', 1 );
    

    instead of

        std::pair<std::string, int> p1 = { "a", 1 };
    

    you would get an error because there is no conversion from std::pair<char, int> to std::pair<std::string, int> because there is no constructor from char to std::string.