Created on 2025-11-11.00:00:00 last changed 7 days ago
Proposed resolution:
This wording is relative to N5014 after application of P3860R1.
[Drafting note: The deleted overloads were mirrored from the design of `reference_wrapper` before LWG 2993. As these overloads don't participate in implicit conversion, I don't think there will be any similar issue introduced.]
Modify [atomics.ref.generic.general], primary class template `atomic_ref` synopsis, as indicated:
namespace std {
template<class T> struct atomic_ref {
private:
T* ptr; // exposition only
public:
[…]
constexpr explicit atomic_ref(T&);
explicit atomic_ref(T&&) = delete;
constexpr atomic_ref(const atomic_ref&) noexcept;
template<class U>
constexpr atomic_ref(const atomic_ref<U>&) noexcept;
[…]
};
}
Modify [atomics.ref.int], class template `atomic_ref` integral-type specialization synopsis, as indicated:
namespace std {
template<> struct atomic_ref<integral-type> {
private:
integral-type* ptr; // exposition only
public:
[…]
constexpr explicit atomic_ref(integral-type&);
explicit atomic_ref(integral-type&&) = delete;
constexpr atomic_ref(const atomic_ref&) noexcept;
template<class U>
constexpr atomic_ref(const atomic_ref<U>&) noexcept;
[…]
};
}
Modify [atomics.ref.float], class template `atomic_ref` floating-point-type specialization synopsis, as indicated:
namespace std {
template<> struct atomic_ref<floating-point-type> {
private:
floating-point-type* ptr; // exposition only
public:
[…]
constexpr explicit atomic_ref(floating-point-type&);
explicit atomic_ref(floating-point-type&&) = delete;
constexpr atomic_ref(const atomic_ref&) noexcept;
template<class U>
constexpr atomic_ref(const atomic_ref<U>&) noexcept;
[…]
};
}
Modify [atomics.ref.pointer], class template `atomic_ref` pointer-type specialization synopsis, as indicated:
namespace std {
template<> struct atomic_ref<pointer-type> {
private:
pointer-type* ptr; // exposition only
public:
[…]
constexpr explicit atomic_ref(pointer-type&);
explicit atomic_ref(pointer-type&&) = delete;
constexpr atomic_ref(const atomic_ref&) noexcept;
template<class U>
constexpr atomic_ref(const atomic_ref<U>&) noexcept;
[…]
};
}
[ 2025-12-05; LWG telecon. Moved to Ready ]
std::atomic_ref<T> has a constructor taking T&, so when `T` is a `const` but not `volatile` object type, the constructor parameter can be bound to a temporary expression, which doesn't seem to make sense. Even after P3860R1, explicitly constructing std::atomic_ref<const T> from std::atomic_ref<volatile T> can be well-formed with the undesired semantics when it is well-formed to instantiate std::atomic_ref<volatile T> and its operator `T` conversion function, because the construction calls the conversion function and creates a temporary object. Probably it's better to disallow such reference binding.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2025-12-05 17:02:14 | admin | set | messages: + msg15784 |
| 2025-12-05 17:02:14 | admin | set | status: new -> ready |
| 2025-11-15 12:53:06 | admin | set | messages: + msg15742 |
| 2025-11-11 00:00:00 | admin | create | |