C++ List of Pairs
Solution 1
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
.
Solution 2
There is no implicit constructor in std::string
that accepts char
and can be used to convert type char
to std::string
. What you can use is this constructor:
basic_string( size_type count, CharT ch, const Allocator& alloc = Allocator() );
so
freq2.push_back(std::make_pair( std::string( 1, *it ),0));
and so on
Solution 3
The issue is that you're attempting to construct a std::string
from a single char. There is no such constructor for std::string
.
Admin
Updated on July 14, 2022Comments
-
Admin almost 2 years
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!
-
dyp almost 10 years@YZ.learner Because, for some reason, there is an assignment-operator that accepts a single character on the rhs.
-
Bill Lynch almost 10 yearsTo elaborate, the call in
freq2
is using constructors. The call infreq
is using the default constructor and then the assignment operator. -
GuLearn almost 10 years@dyp There is no "signle character" on the rhs. make_pair returns a
std::pair
-
Bill Lynch almost 10 years@YZ.learner: Internally, the pair will use
operator=
when making the assignment. -
Bill Lynch almost 10 years@YZ.learner: Note the difference between:
std::pair<std::string, int> fails('S', 0);
andstd::pair<std::string, int> works; works = std::make_pair('S', 0);
. -
GuLearn almost 10 years@sharth, Well, I guess my question then would be why can you assign an object of type
std::pair<std::string, int>
to a value of typestd::pair<char, int>
-
David Tr almost 10 yearsBut for the second set of statements, doesn't std::make_pair have to construct the object first before it will be reassigned to the pair in freq?
-
Bill Lynch almost 10 years@YZ.learner: Because it has an assignment operator that looks like this:
std::pair<T1, T2> = std::pair<U1, U2>
, the lhs and rhs don't have to be the same types. We just require that we can doT1 = U1
andT2 = U2
. -
fjardon almost 10 yearsPlease add this to your answer. +1
-
Vlad from Moscow almost 10 years@David Tr It constructs an object of type std::pair<char, int>.
-
David Tr almost 10 yearsOh that makes perfect sense now, your example after the fact made sense. I didn't know the assignment operator worked like that on a pair object. Good explanation.
-
Admin almost 10 yearsI like that explanation @sharth