【问题标题】:What happened to std::atomic<X>::value_type?std::atomic<X>::value_type 发生了什么?
【发布时间】:2019-05-07 23:38:59
【问题描述】:

根据this reference manual

对于每个std::atomic&lt;X&gt;(无论是否特化),std::atomic&lt;X&gt;::value_type 都是 X。

但是如果我尝试使用这种类型,我会得到一个编译错误。

我已经用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;

并且使用 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;
~~~~~~~~~~~~~~~~~~^

上面提到的参考手册还规定了……

规范被大幅重写以解决许多问题 特别是增加了成员typedefs value_type和difference_type

P0558R1 规范似乎并没有禁止 value_type 的存在。

知道发生了什么吗?

编辑

我的一位同事让我意识到 P0558R1 只是一个提案。

【问题讨论】:

  • P0558R1 adds value_type 和 difference_type,由于它被视为 DR,因此它追溯适用于 C++11。
  • cppreference中的“特别是添加了成员​​typedefs value_type和difference_type”部分是我添加的,很遗憾它导致的效果与我预期的相反。
  • 作为缺少T::value_type的一种解决方法,可以尝试使用decltype(T.load())

标签: c++ c++11 gcc clang


【解决方案1】:

您明确使用 C++11。如果我们查看 C++11 标准的 last draft 的第 1119 页,没有提到 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);
};

C++14 草案中同样没有。

cppreference 只是没有提及 value_type 的“自 C++17 以来”。

编辑:有人指出,添加value_type 是以缺陷报告的形式添加的,应该追溯应用于 C++11 的实现。因此,cppreference 实际上并没有错,只是在给定的编译器版本中没有实现 DR。

【讨论】:

  • 只是不完整。
  • 哦,也许 cppreference 只是忘了提到 value_type 仅在某些更高版本的 C++ 之后才可用?
  • 我修复了 cppreference 页面 :)
  • 出于某种原因,我在 cppreference 中的修复已被撤消。很公平:)
【解决方案2】:

鉴于 P0558R1 的性质,我预计它最终会在以前的标准模式中作为事实上的缺陷报告追溯实施,并据此记录下来。本文对依赖于这些 typedef 存在的非成员函数模板进行了大手术。实施者通常追溯应用类似的手术。作为数据点,唯一已知的完全实现 P0558R1 (MSVC) 的主要实现是这样做的,与语言版本无关。

cppreference 的目标是假设每个 C++ 标准的完整和正确实现以及适用于该标准的所有缺陷报告和说明。

【讨论】:

    猜你喜欢
    • 2016-09-04
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 2017-09-06
    • 2020-01-11
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    相关资源
    最近更新 更多