This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
std::atomic_ref<const T> can be constructed from temporariesSection: 32.5.7 [atomics.ref.generic] Status: New Submitter: Jiang An Opened: 2025-11-11 Last modified: 2025-11-15
Priority: Not Prioritized
View all other issues in [atomics.ref.generic].
View all issues with New status.
Discussion:
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.
Proposed resolution:
This wording is relative to N5014 after application of P3860R1.
[Drafting note: The deleted overloads were mirrored from the design of
reference_wrapperbefore LWG 2993(i). As these overloads don't participate in implicit conversion, I don't think there will be any similar issue introduced.]
Modify 32.5.7.1 [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 32.5.7.3 [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 32.5.7.4 [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 32.5.7.5 [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;
[…]
};
}