In the class defined as below named foo
class foo{
private:
string str;
public:
foo operator = (string s){
str = s;
}
};
int main(){
foo a = "this initialization throwing an error";
foo b;
b = "but assignment after declaration is working fine";
}
error: conversion from 'const char [38]' to non-scalar type 'foo' requested
The above error is caused only when I am assigning value to the object instance with declaration but if I am assigning separately from declaration then the overloaded equal =
operator is working fine.
I want in any method to assign an string to the object with equal operator
and as a declaration like foo a = "abcd";
When you have
type name = something;
You are not doing assignment but instead you have copy-initialization (do not that there can be a move even though it is called copy). This means that you need a constructor in your class whose parameter matches that of the thing on the right hand side of the =
.
In this case you do not have a constructor that takes a std::string
, const char*
or const char[]
so the compiler is unable to construct an instance there.
The reason the second case works is that
b = "but assignment after declaration is working fine";
Is not trying to construct anything and therefore it calls the assignment operator which does work because
"but assignment after declaration is working fine"
can be converted to a std::string
.
If you want your class to be constructable from a string literal or cstring then you can add a constructor to it in the form of
foo(const char* str) : str(str) {}
What you have in the first case is called copy initialization and as stated in documentation:
The equals sign, =, in copy-initialization of a named variable is not related to the assignment operator. Assignment operator overloads have no effect on copy-initialization.
Hense the error. So possible solutions:
First you can create a constructor, that accepts std::string
:
foo( const std::string &s );
that will allow you to create foo
by this:
foo f( "abc" );
or even this:
foo f = foo( "abc" );
but your statement will still fail, because of:
in addition, the implicit conversion in copy-initialization must produce T directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument of T's constructor.
so to make your statement work as it is you need to add this ctor:
foo( const char *str );
Note: when you add proper ctor you do not need to define assignment operator - conversion constructor will be used. And your overloaded assignment operator should return reference to foo
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With