0

I have a class with copy constructor and copy assign operator deleted. Move constructor amd move-assign operator are present. It also defines an operator<<:

struct S
{
    S(std::size_t s) {}

    S(const S &) = delete;
    S(S &&) { std::cout << "S&&"; }
    S &operator =(const S &) = delete;
    S &operator =(S &&) { std::cout << "=S&&"; return *this; }

    S &operator<<(int) { return *this; }
};

Also I've added an user defined literal:

S operator ""_S(const char *const c, std::size_t s)
{
    return s;
}

Then I use the S object like this:

/* Error: */ auto s1 = "Test"_S << 1 << 2 << 3;
/* Ok:    */ auto s2 = "123"_S;

The error I'm getting is:

.code.tio.cpp:22:20: error: call to deleted constructor of 'S'
        /* Error: */ auto s1 = "Test"_S << 1 << 2 << 3;
                          ^    ~~~~~~~~~~~~~~~~~~~~~~~
.code.tio.cpp:7:2: note: 'S' has been explicitly marked deleted here
        S(const S &) = delete;
        ^

I thought that the Error case would be valid and trigger the operator=(S &&) since "Test"_S << 1 << 2 << 3 is a temporary expression. Also nothing is printed on the output window but I was expecting to see =S&&=S&&.

Obviously I'm wrong on all my assumptions, what's happening here?

  • Why s1 is not move-asigned from "Test"_S << 1 << 2 << 3 expression?
  • Is s2 created in-place with the "123"_S expression thus avoiding the move-assign operator?
PaperBirdMaster
  • 12,806
  • 9
  • 48
  • 94
  • You should mention what the error is, though: https://godbolt.org/z/71hTvnq89 . About the second point, yes, the constructor is called, not the move assignment. – Bob__ Aug 02 '23 at 08:04

1 Answers1

2

Why s1 is not move-assigned from "Test"_S << 1 << 2 << 3 expression?

operator<< returns a reference, but the copy constructor is deleted. You might do something like this

struct S
{
    S(std::size_t s) { std::cout << "ctor\n"; }

    S(const S &) = delete;
    S(S &&) { std::cout << "S&&"; }
    S &operator =(const S &) = delete;
    S &operator =(S &&) { std::cout << "=S&&"; return *this; }

    S operator<<(int) { return std::move(*this); }
//   ^                         ^^^^^^^^^    
};

Which will output1

ctor
S&&S&&S&&ctor

1) https://godbolt.org/z/9Ef6PWz86

Bob__
  • 12,361
  • 3
  • 28
  • 42