Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

initialise object with equal operator

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";

like image 750
Abhay Jatin Doshi Avatar asked Jan 05 '23 01:01

Abhay Jatin Doshi


2 Answers

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) {}
like image 199
NathanOliver Avatar answered Jan 07 '23 15:01

NathanOliver


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.

like image 40
Slava Avatar answered Jan 07 '23 14:01

Slava