Construction enigma

Hello there,
I got a problem with constructors. Until now I thought, that the expression 'Object o = value' is equivalent to 'Object o(value)', but now I doubt it. Here's the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>

using namespace std;

class foo
{
public:
    foo(const string&){cout << "foo(const string&)" << endl;}
    // Without this the Construction with the assignment-operator doesn't work:
    //foo(const char*){cout << "foo(const char*)" << endl;}

    // Isn't called, regardless of the construction method:
    foo& operator=(const char*)
    {
        cout << "operator=" << endl;
        return *this;
    }
};

int main()
{
    //foo f = "hello!"; // compile time error without foo(const char*)
    foo g("Yeeha!"); // Does work without foo(const char*)

    return 0;
}


I know how the method foo(const string&) works with the literal constant (initializes a temporary, and therefore constant, string object with the literal constant). But if it takes the const char* in an explicit construction, why doesn't the construction via assignment operator work?

I appreciate any help. Thanks in advance,
byte a bit
Here is one way to look at it:

operator= is always a non-static member function.

It needs to be called on a fully constructucted object ( modifiable Lvalue)

A = B is the same as A.operator=(B) - which means that A and B must be both fully constructed for assignment to take place.
And as object A is the object carrying out the assignment - it
must be an existing fully cqualified object - therefore you cannot construct object A using operator=


Last edited on
Dear guestgulkan,

thanks for your reply. But my question is, if 'Object o = value' is equivalent to 'Object o(value)'. Because you can construct a std::string like this 'std::string = "hello";' No assignment operator needed. I just overloaded it to see, if it gets called somehow, beause I couldn't find a reason for the Construction behaviour.

I'm still interested in your thoughts about it.
Until now I thought, that the expression 'Object o = value' is equivalent to 'Object o(value)', but now I doubt it

It isn't exactly equivalent.
"Object o = value" is copy-initialization
http://en.cppreference.com/w/cpp/language/copy_initialization

"Object o(value)" is direct initialization
http://en.cppreference.com/w/cpp/language/direct_initialization

The difference is, to quote: "copy-initialization only considers non-explicit constructors and user-defined conversion functions, while direct-initialization considers all constructors and implicit conversion sequences."

Given a const char[7] argument, your compiler has to decide between three candidate functions:
1
2
3
foo(const foo&) // the compiler-generated copy constructor
foo(foo&&) // the compiler-generated move constructor
foo(const std::string&) // the user-defined constructor 

None of these is acceptable for copy-initialization (there is no implicit conversion from character literals to std::strings, or to your class). The third one is acceptable for direct-initialization: there is converting constructor that std::string has, which builds it from a const char*.

When you add a foo(const char*), copy-initialization is compiled because a non-explicit single-argument constructor is acceptable, and direct initialization begins using the new constructor too, because it's a better match.
Last edited on
Thanks a lot! Only one thing: If I add a user defined Constructor, the Compiler should not generate any constructors itself, as far as I know.

Regards, byte a bit
If I add a user defined Constructor, the Compiler should not generate any constructors itself, as far as I know
A user-defined constructor only suppresses the default constructor generation. Copy and move are still made.
Topic archived. No new replies allowed.