为什么互斥量和条件变量可以微不足道地复制? [英] Why are mutexes and condition variables trivially copyable?

查看:145
本文介绍了为什么互斥量和条件变量可以微不足道地复制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

LWG 2424 讨论了原子的不良状态,在C ++ 14中,互斥体和条件变量为普通可复制.我很感激,此修复程序已已排队,但 std::mutex

LWG 2424 discusses the undesirable status of atomics, mutexes and condition variables as trivially copyable in C++14. I appreciate that a fix is already lined up, but std::mutex, std::condition variable et al. appear to have non-trivial destructors. For example:

30.4.1.2.1类互斥锁[thread.mutex.class]

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

    …
  }
}

这不应该使他们失去可复制的资格吗?

Shouldn't this disqualify them as trivially copyable?

推荐答案

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

Either it was my mistake, or I was misquoted, and I honestly don't recall which.

但是,我对此有非常强烈的建议:

However, I have this very strongly held advice on the subject:

请勿使用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>

理论上:

tldr::请参见此优秀问题和正确答案.

没有人(包括我自己)记得is_trivialis_trivially_copyable的定义.而且,如果确实要查找它,然后花10分钟对其进行分析,则它可能会或可能不会执行您直觉上认为的事情.并且,如果您设法对其进行正确分析,则CWG可能会在很少或根本没有通知的情况下更改其定义,并使您的代码无效.

No one (including myself) can remember the definition of is_trivial and is_trivially_copyable. And if you do happen to look it up, and then spend 10 minutes analyzing it, it may or may not do what you intuitively think it does. And if you manage to analyze it correctly, the CWG may well change its definition with little or no notice and invalidate your code.

使用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>

完全按照听起来的样子做,并且不可能更改其定义.必须单独处理每个特殊成员似乎过于冗长.但这将使代码的稳定性/可靠性得到回报.而且,如果必须的话,可以将这些个体特征打包成自定义特征.

do exactly what they sound like they do, and are not likely to ever have their definition changed. It may seem overly verbose to have to deal with each of the special members individually. But it will pay off in the stability/reliability of your code. And if you must, package these individual traits up into a custom trait.

更新

例如,clang& gcc编译该程序:

For example, clang & gcc compile this program:

#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 可以被复制,但是不可可以被复制.据我所知,这是合规行为.

Note that X is trivially copyable, but not trivially copy constructible. To the best of my knowledge, this is conforming behavior.

VS-2015当前表示X既不可复制也不可构建.我认为根据当前规范,这是错误的,但可以肯定符合我的常识告诉我.

VS-2015 currently says that X is neither trivially copyable nor trivially copy constructible. I believe this is wrong according to the current spec, but it sure matches what my common sense tells me.

如果我需要memcpy未初始化的内存,我会相信is_trivially_copy_constructible而不是is_trivially_copyable,以确保可以进行此操作.如果我想memcpy来初始化 内存,我会检查is_trivially_copy_assignable.

If I needed to memcpy to uninitialized memory, I would trust is_trivially_copy_constructible over is_trivially_copyable to assure me that such an operation would be ok. If I wanted to memcpy to initialized memory, I would check is_trivially_copy_assignable.

这篇关于为什么互斥量和条件变量可以微不足道地复制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆