gpt4 book ai didi

c++ - 为什么互斥锁和条件变量可以轻松复制?

转载 作者:IT老高 更新时间:2023-10-28 23:16:13 27 4
gpt4 key购买 nike

LWG 2424讨论原子、互斥体和条件变量的不良状态为 trivially copyable在 C++14 中。我很感激修复是 already lined up , 但是 std::mutex , std::condition variable等。似乎有非平凡的析构函数。例如:

30.4.1.2.1 Class mutex [thread.mutex.class]

namespace std {
class mutex {
public:
constexpr mutex() noexcept;
~mutex(); // user-provided => non-trivial


}
}

这难道不应该取消它们的可复制性吗?

最佳答案

要么是我的错误,要么是我被错误引用了,老实说,我不记得是哪一个。

但是,我对此主题有以下非常强烈的建议:

Do not use is_trivial nor is_trivially_copyable! EVER!!!

改为使用以下之一:

is_trivially_destructible<T>
is_trivially_default_constructible<T>
is_trivially_copy_constructible<T>
is_trivially_copy_assignable<T>
is_trivially_move_constructible<T>
is_trivially_move_assignable<T>

理由:

tldr:excellent question and correct answer.

没有人(包括我自己)能记住is_trivialis_trivially_copyable的定义。如果你碰巧查了一下,然后花 10 分钟分析它,它可能会也可能不会像你直觉认为的那样做。如果您设法正确分析它,CWG 很可能会在很少或根本不通知的情况下更改其定义,并使您的代码无效。

使用 is_trivialis_trivially_copyable 是在玩火。

但是这些:

is_trivially_destructible<T>
is_trivially_default_constructible<T>
is_trivially_copy_constructible<T>
is_trivially_copy_assignable<T>
is_trivially_move_constructible<T>
is_trivially_move_assignable<T>

做他们听起来像他们做的事情,并且不太可能改变他们的定义。必须单独处理每个特殊成员似乎过于冗长。但它会在代码的稳定性/可靠性方面得到返回。如果必须,将这些单独的特征打包成一个自定义特征。

更新

例如,clang & gcc 编译这个程序:

#include <type_traits>

template <class T>
void
test()
{
using namespace std;
static_assert(!is_trivial<T>{}, "");
static_assert( is_trivially_copyable<T>{}, "");
static_assert( is_trivially_destructible<T>{}, "");
static_assert( is_destructible<T>{}, "");
static_assert(!is_trivially_default_constructible<T>{}, "");
static_assert(!is_trivially_copy_constructible<T>{}, "");
static_assert( is_trivially_copy_assignable<T>{}, "");
static_assert(!is_trivially_move_constructible<T>{}, "");
static_assert( is_trivially_move_assignable<T>{}, "");
}

struct X
{
X(const X&) = delete;
};

int
main()
{
test<X>();
}

请注意,X 可简单复制的,但不是可简单复制构造的。据我所知,这是符合规范的行为。

VS-2015 目前表示 X 既不 可简单复制也不可简单复制构造。根据目前的规范,我认为这是错误的,但它确实符合我的常识。

如果我需要 memcpyuninitialized 内存,我会信任 is_trivially_copy_constructible 而不是 is_trivially_copyable 向我保证这样的操作就可以了。如果我想 memcpyinitialized 内存,我会检查 is_trivially_copy_assignable

关于c++ - 为什么互斥锁和条件变量可以轻松复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36160343/

27 4 0