According to this reference manual
For every
std::atomic<X>
(whether or not specialized),std::atomic<X>::value_type
is X.
But if I try using such type I get a compilation error.
I've tried it with g++ 8.2.1
:
$ g++ -std=c++11 test.cc
test.cc: In function ‘int main()’:
test.cc:6:23: error: ‘value_type’ is not a member of ‘std::atomic<int>’
std::atomic<int>::value_type x = 0;
And with clang 6.0.1
$ clang -std=c++11 test.cc
test.cc:6:23: error: no type named 'value_type' in 'std::atomic<int>'
std::atomic<int>::value_type x = 0;
~~~~~~~~~~~~~~~~~~^
The afore mentioned reference manual specifies also says that...
specification was substantially rewritten to resolve numerous issues in particular, member typedefs value_type and difference_type are added
The P0558R1 specification however seems not to forbid the existence of value_type
.
Any idea what's going on?
A colleague of mine made me realize that P0558R1 is just a proposal.
You are explicitly using C++11. If we look at page 1119 of the last draft of the C++11 standard, there is no mention of value_type
for std::atomic
:
template <class T> struct atomic {
bool is_lock_free() const volatile;
bool is_lock_free() const;
void store(T, memory_order = memory_order_seq_cst) volatile;
void store(T, memory_order = memory_order_seq_cst);
T load(memory_order = memory_order_seq_cst) const volatile;
T load(memory_order = memory_order_seq_cst) const;
operator T() const volatile;
operator T() const;
T exchange(T, memory_order = memory_order_seq_cst) volatile;
T exchange(T, memory_order = memory_order_seq_cst);
bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile;
bool compare_exchange_weak(T&, T, memory_order, memory_order);
bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile;
bool compare_exchange_strong(T&, T, memory_order, memory_order);
bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst) volatile;
bool compare_exchange_weak(T&, T, memory_order = memory_order_seq_cst);
bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst) volatile;
bool compare_exchange_strong(T&, T, memory_order = memory_order_seq_cst);
atomic() = default;
constexpr atomic(T);
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
T operator=(T) volatile;
T operator=(T);
};
It is similarly absent in the C++14 draft.
cppreference just fails to mention "since C++17" for value_type
.
Edit: It has been pointed out that the addition of value_type
was in the form of a defect report and should be applied retroactively to implementations of C++11. As such, cppreference is not actually wrong, the DR just has not been implemented in the given compiler versions.
Given the nature of P0558R1, I expected it to be eventually implemented retroactively in previous standard modes as a de facto defect report and documented it as such. The paper performs major surgeries on the non-member function templates that depend on the presence of these typedefs. Similar surgeries have generally been applied retroactively by implementers. As a data point, the only major implementation known to have fully implemented P0558R1 (MSVC) does so regardless of language version.
cppreference's target is a hypothetical complete and correct implementation of each C++ standard plus all defect reports and clarifications applicable to that standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With