For starters though the compiler does not issue a diagnostic message nevertheless the assignment operator in the class definition
class foo{
private:
string str;
public:
foo operator = (string s){
str = s;
}
};
is invalid because it returns nothing while it has return type foo
.
You should it write like
foo & operator = ( const std::string &s){
str = s;
return *this;
}
As you declared neither the default constructor nor the copy constructor then the compiler implicitly declared them instead of you.
So in fact your class has only two constructor. The default constructor that has the following declaration
foo();
and the copy constructor that has the following declaration
for( const foo & );
In this statement
foo a = "this initialization throwing an error";
the compiler assumes that in the right side there is an object of type foo
and you are going to use it to create the object a
. That is in this declaration the compiler tries to apply the implicitly created copy constructor. To so so it need to convert the string literal to an object of type foo
. However the class does not have a conversion constructor that is a constructor with a parameter that can accept the string literal. As result the compiler issues the error
error: conversion from 'const char [38]' to non-scalar type 'foo'
requested
const char[33]
is the type of the string literal in the right side of the declaration.
In this code snippet
foo b;
b = "but assignment after declaration is working fine";
at first there is created the object b
of the type foo
using the implicitly defined by the compiler default constructor and then in the second statement there is used the assignment operator that is explicitly defined in the class. As it follows from the definition of the operator it assigns data member str
with a temporary object of type std::string
that is constructed from the used string literal. It is possible because the class std::string
has a corresponding conversion constructor.