Home > Enterprise >  Why t =i 'a' gives correct output while t=t i 'a' gives error in C
Why t =i 'a' gives correct output while t=t i 'a' gives error in C

Time:06-10

I have been working on some question that involves converting ASCII value into string. For that I am using following code.

If I use this code then I get output as "g".

using namespace std;
int main()
{
int i=6; vector<string> ans;
string t= "";
t =i 'a';
ans.push_back(t);
cout<<ans[0];

return 0;

However if I use below code, it gives error :

using namespace std;
int main()
{
int i=6; vector<string> ans;
string t= "";
t=t i 'a';
ans.push_back(t);
cout<<ans[0];

return 0;

Following error is shown when I execute above code : error: no match for 'operator ' (operand types are 'std::string' {aka

'std::__cxx11::basic_string'} and

'int')

7 t=t i 'a';

~^~

| int

std::string {aka

std::__cxx11::basic_string}

The only difference between both the code is that in 1st code, I am using t= i 'a'; while in second, t=t i 'a'; is used.

The Error in showing in C Language

Can someone please tell why it is showing error in second part. Thanks in advance

CodePudding user response:

1. The t = i 'a'; case

Here, two things are important. First,

std::string& std::string::operator =(char ch);

is called, which is a non-template member function of the std::string class (that is, of the std::basic_string<char> class template instance); see https://en.cppreference.com/w/cpp/string/basic_string/operator+=.

Second, the type of i 'a' is int.

Everything works fine, since the argument i 'a' of type int can be used as an argument for a function parameter of type char.

2. The t = t i 'a'; case

In contrast to case 1., operator is used here, first for the t i part, where i is of type int. But opeartor is a free (non-member) function template; see https://en.cppreference.com/w/cpp/string/basic_string/operator+.

The compiler tries to instantiate this definition:

template<class CharT, class Traits, class Alloc>
std::basic_string<CharT,Traits,Alloc>
operator ( const std::basic_string<CharT,Traits,Alloc>& lhs, CharT rhs );

But it can't since according to the first argument of type std::string, CharT would be deduced as char, but according to the second argument of type int, CharT would be deduced as int. Therefore, duduction conflict happens. And, there is no other template that might be instantiated.


Simple demo code of the same problem:

template <typename Char>
struct String
{
    String& operator =(Char);
};

template <typename Char>
String<Char> operator (const String<Char>&, Char);

int main()
{
    String<char> s;
    s  = 2   'a';
    s = s   2   'a';
}

Live link: https://godbolt.org/z/MonK1e3bq

CodePudding user response:

The problem in case 2 is that the statement t = t i 'a' is actually grouped as(or equivalent to) t = (t i) 'a' due to operator precedence.

//---v---v--------->t is std::string while i is an int
t = (t   i)   'a'; //equivalent to this due to operator precedence

Now as t is a std::string and i is an int and since there is no overloaded operator that takes an std::string and a int, we get the mentioned error.


Note that is an arithmetic operator and so in the first case, the character literal 'a' is promoted to int when writing i 'a'. And since std::string has the overload string& string::operator = (char) that can be used, the first case uses that overloaded operator =.

CodePudding user response:

Basically you are trying to add an integer to a string which does not work even in python. Even in python you need a str(myInt) to concatenate that integer with a string.

Therefore, if you want to concatenate an integer to a string you will need this:

 t=t to_string(i) 'a';

It might not be the best theoretical answer, but in daily live you will use it a lot.

  • Related