【问题标题】:GCC 8 fails to compile make_shared<volatile int>()GCC 8 无法编译 make_shared<volatile int>()
【发布时间】:2019-02-15 13:01:26
【问题描述】:

这段代码编译干净,可以与我尝试过的所有编译器一起使用,除了 GCC 8(和当前的 GCC 主干):

std::make_shared<volatile int>(0)

我想知道:

  1. GCC 8 拒绝此代码是否正确?
  2. 是否有 GCC 8 可以接受的替代品(具有相同的语义和性能)?我知道std::atomic,但语义不一样,所以使用它而不是volatile 的建议不是我想要的。

在这里查看:https://godbolt.org/z/rKy3od

【问题讨论】:

  • 澄清一点:你知道volatile 不会给你任何线程安全,也不保证不会有优化?
  • I am aware of std::atomic, but the semantics are not the same so suggestions to use it instead of volatile are not what I'm looking for. 你在寻找什么语义?我会更容易为你找到替代品。
  • IDK 您的用例,但以下解决方法,即使 GCC 4.8 也接受,可能对您有用(添加 volatile 是完全安全的,static_pointer_cast 也适用):std::const_pointer_cast&lt;volatile int&gt;(std::make_shared&lt;int&gt;(0))跨度>
  • @ArneVogel:感谢您的提示。这似乎工作正常:shared_ptr&lt;volatile int&gt; p = make_shared&lt;int&gt;(0).

标签: c++ c++11 gcc volatile make-shared


【解决方案1】:

根据标准语言,这是不符合 libstdc++ 的。

这可能是一个错误。 make_shared 使用标准分配器std::allocator&lt;remove_const_t&lt;T&gt;&gt; 调用allocate_shared,其中T 是共享对象的类型。此分配器将仅用于为底层共享对象(包含 volatile int 和原子计数器的结构)获取重新绑定的分配器。因此,将这个底层对象声明为非 const 非易失性完全没问题。

make_shared 的这个定义将起作用:

template<class T,class...Args>
auto make_shared(Args&&...args){
    using ncvT= std::remove_cv_t<T>;
    return std::allocate_shared<T>(std::allocator<ncvT>(),std::forward<Args>(args)...);
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-14
  • 1970-01-01
  • 2020-05-18
  • 2013-01-29
  • 1970-01-01
相关资源
最近更新 更多