-
Notifications
You must be signed in to change notification settings - Fork 803
Closed
Labels
cwgIssue must be reviewed by CWG.Issue must be reviewed by CWG.
Description
The title section currently reads:
A defaulted copy/move assignment operator for class X is defined as deleted if X has:
- a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
- a non-static data member of const non-class type (or array thereof), or
- a non-static data member of reference type, or
- a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.
What is the "corresponding assignment operator"? Consider the following example (from @foonathan):
#include <type_traits>
//=== the setup ===//
// This class is weird, but Microsoft's std::pair works the same.
struct foo
{
// foo has a trivial default constructor, copy constructor, move constructor and destructor.
foo() = default;
foo(const foo&) = default;
foo(foo&&) = default;
~foo() = default;
// For the compiler, this is a copy assignment operator.
// http://eel.is/c++draft/class.copy.assign#1
foo& operator=(const volatile foo&) = delete;
// For the compiler, this is not a copy assignment operator.
// This is just a weird operator overload.
template <int Dummy = 0>
foo& operator=(const foo&) // non-trivial
{
return *this;
}
// For the compiler, this is not a move assignment operator.
// This is just a weird operator overload.
template <int Dummy = 0>
foo& operator=(foo&&) // non-trivial
{
return *this;
}
};
template <typename T>
struct my_optional
{
union
{
char empty;
T value;
};
};
static_assert(!std::is_copy_assignable_v<my_optional<foo>>);All compilers agree that my_optional<foo> is not copy assignable, because copy assignment would be non-trivial. But the variant member T value here does have a trivial copy assignment operator (the "corresponding assignment operator") -- but it's not the one that would be used when performing copy assignment.
We need to do the same "overload resolution ([over.match]), as applied to find M's corresponding assignment operator" thing from the 4th bullet point to also handle the 1st bullet point cases.
Metadata
Metadata
Assignees
Labels
cwgIssue must be reviewed by CWG.Issue must be reviewed by CWG.