C++ Logo

std-discussion

Advanced search

LWG 3661 broke `atomic<shared_ptr<T>> a; a = nullptr; `?

From: Zachary Wassall <z.wassall_at_[hidden]>
Date: Tue, 21 Feb 2023 18:31:53 -0500
Hi all,

LWG 3661: "`constinit atomic<shared_ptr<T>> a(nullptr);` should work" added
the following to `atomic<shared_ptr<T>>`:

```
constexpr atomic(nullptr_t) noexcept : atomic() { }
```

I believe that doing so broke the following example:

```
atomic<shared_ptr<T>> a;
a = nullptr;
```

For reference, `atomic<shared_ptr<T>>` provides two assignment operator
overloads:

```
void operator=(const atomic&) = delete; // #1
void operator=(shared_ptr<T> desired) noexcept; // #2
```

Prior to LWG 3611, the assignment in the example unambiguously matches #2.
#1 is not viable because `nullptr_t` is not convertible to
`atomic<shared_ptr<T>>`. After LWG 3611, #1 is viable and the assignment is
ambiguous between #1 and #2.

This seems like a proper defect, right? I'm here seeking some confirmation
before submitting an issue.

I believe this could be remedied easily enough by adding an assignment
operator to match the added `nullptr_t ` constructor:

```
void operator=(nullptr_t) noexcept;
```

Thanks,
 - Zack

Received on 2023-02-21 23:32:05