Description
Title: The meaning of operator=
with multiple non-this
parameters.
Description:
An operator=
with multiple non-this
parameters
doesn't work with non definite first assignment.
Looking at #449, it seems like we expect it to work.
I think that is consistent with https://github.com/hsutter/cppfront/wiki/Cpp2:-operator=,-this-&-that#misc-notes's
More generally, writing
=
always invokes anoperator=
(in fact for a Cpp2-authored type, and semantically for a Cpp1-authored type). This avoids the Cpp1 inconsistency that "writing=
callsoperator=
, except when it doesn't" (such as in a Cpp1 variable initialization). Conversely,operator=
is always invoked by=
.
Besides #449, further integration is also the objective of #368, and perhaps also of #409.
#321 is another such issue, but = (...)
is intended for an std::initializer_list
parameter.
Minimal reproducer (https://cpp2.godbolt.org/z/q1WvTaEnM):
t: type = {
// operator=: (out this, x, y) = { }
operator=: (inout this, x, y) = { }
}
main: () = { }
Commands.
cppfront -clean-cpp1 main.cpp2
clang++17 -std=c++2b -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -I . main.cpp
Expected result:
As you can see below, cppfront
currently lowers to
a Cpp1 assignment operator with multiple arguments, which is ill-formed.
In order for this to work, it'd have to be lowered to a Cpp1 cpp2_assign
overload
(inspired from the C++ standard library containers assign
member functions):
public: auto cpp2_assign(auto const& x, auto const& y) -> t& ;
Here's where it gets contentious with #321.
Cpp2 a = (x, y)
would have to choose between
Cpp1 a = {x, y}
and
Cpp1 a.cpp2_assign(x, y)
.
Actual result and error:
public: auto operator=(auto const& x, auto const& y) -> t& ;
build/_cppfront/main.cpp:9:16: error: overloaded 'operator=' must be a binary operator (has 3 parameters)
public: auto operator=(auto const& x, auto const& y) -> t& ;
^
Cpp2 lowered to Cpp1.
#include "cpp2util.h"
class t;
class t {
// operator=: (out this, x, y) = { }
public: auto operator=(auto const& x, auto const& y) -> t& ;
public: t() = default;
public: t(t const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(t const&) -> void = delete;
};
auto main() -> int;
auto t::operator=(auto const& x, auto const& y) -> t& {
return *this;
}
auto main() -> int{}