You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

持有trivially copyable类型的WMutable<T>是否应属trivially copyable?

关于WMutable<T>是否属于trivially copyable的编译器分歧问题

示例代码如下:

我们定义了4个类:

  • S<T>:包含一个数据成员。
  • SCtor<T>:包含一个数据成员,且拥有模板构造函数。
  • SCtorMutable<T>:包含一个mutable数据成员,且拥有模板构造函数。
  • SCtorDefault<T>:包含一个成员,拥有模板构造函数,且显式默认了复制/移动构造函数与复制/移动赋值运算符。

所有编译器均判定这4个类为trivially copyable。

若使用普通包装类W<T>持有上述任一类作为数据成员,包装类W<S...<T>>仍会被判定为trivially copyable。

但若使用另一个包装类WMutable<T>持有上述任一类作为mutable数据成员,不同编译器的判定出现分歧:

  • MSVC仍判定WMutable<S...<T>>为trivially copyable。
  • clang判定WMutable<S<T>>为trivially copyable,但WMutable<SCtor...<T>>因非平凡复制构造,不属trivially copyable。
  • gcc判定WMutable<S<T>>为trivially copyable,WMutable<SCtor...<T>>虽非平凡复制构造,但仍属trivially copyable。

那么,WMutable<T>是否应被判定为trivially copyable?

#include <type_traits>
#include <utility>

template<typename T>
struct S {
    T m_t;
};

template<typename T>
struct SCtor {
    T m_t;
    template<typename... U>
    SCtor(U&&... u): m_t(std::forward<U>(u)...) {}
};

template<typename T>
struct SCtorMutable {
    mutable T m_t;
    template<typename... U>
    SCtorMutable(U&&... u): m_t(std::forward<U>(u)...) {}
};

template<typename T>
struct SCtorDefault {
    T m_t;
    template<typename... U>
    SCtorDefault(U&&... u): m_t(std::forward<U>(u)...) {}
    SCtorDefault(SCtorDefault const&) = default;
    SCtorDefault(SCtorDefault&&) = default;
    SCtorDefault& operator=(SCtorDefault const&) = default;
    SCtorDefault& operator=(SCtorDefault&&) = default;
};

template<typename T>
struct W {
    T m_t;
};

template<typename T>
struct WMutable {
    mutable T m_t;
};

static_assert(std::is_trivially_copyable<S<int>>::value);
static_assert(std::is_trivially_copy_constructible<S<int>>::value);
static_assert(std::is_trivially_move_constructible<S<int>>::value);
static_assert(std::is_trivially_copy_assignable<S<int>>::value);
static_assert(std::is_trivially_move_assignable<S<int>>::value);

static_assert(std::is_trivially_copyable<SCtor<int>>::value);
static_assert(std::is_trivially_copy_constructible<SCtor<int>>::value);
static_assert(std::is_trivially_move_constructible<SCtor<int>>::value);
static_assert(std::is_trivially_copy_assignable<SCtor<int>>::value);
static_assert(std::is_trivially_move_assignable<SCtor<int>>::value);

static_assert(std::is_trivially_copyable<SCtorMutable<int>>::value);
static_assert(std::is_trivially_copy_constructible<SCtorMutable<int>>::value);
static_assert(std::is_trivially_move_constructible<SCtorMutable<int>>::value);
static_assert(std::is_trivially_copy_assignable<SCtorMutable<int>>::value);
static_assert(std::is_trivially_move_assignable<SCtorMutable<int>>::value);

static_assert(std::is_trivially_copyable<SCtorDefault<int>>::value);
static_assert(std::is_trivially_copy_constructible<SCtorDefault<int>>::value);
static_assert(std::is_trivially_move_constructible<SCtorDefault<int>>::value);
static_assert(std::is_trivially_copy_assignable<SCtorDefault<int>>::value);
static_assert(std::is_trivially_move_assignable<SCtorDefault<int>>::value);

static_assert(std::is_trivially_copyable<W<S<int>>>::value);
static_assert(std::is_trivially_copy_constructible<W<S<int>>>::value);
static_assert(std::is_trivially_move_constructible<W<S<int>>>::value);
static_assert(std::is_trivially_copy_assignable<W<S<int>>>::value);
static_assert(std::is_trivially_move_assignable<W<S<int>>>::value);

static_assert(std::is_trivially_copyable<W<SCtor<int>>>::value);
static_assert(std::is_trivially_copy_constructible<W<SCtor<int>>>::value);
static_assert(std::is_trivially_move_constructible<W<SCtor<int>>>::value);
static_assert(std::is_trivially_copy_assignable<W<SCtor<int>>>::value);
static_assert(std::is_trivially_move_assignable<W<SCtor<int>>>::value);

static_assert(std::is_trivially_copyable<W<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_copy_constructible<W<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_move_constructible<W<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_copy_assignable<W<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_move_assignable<W<SCtorMutable<int>>>::value);

static_assert(std::is_trivially_copyable<W<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_copy_constructible<W<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_move_constructible<W<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_copy_assignable<W<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_move_assignable<W<SCtorDefault<int>>>::value);

static_assert(std::is_trivially_copyable<WMutable<S<int>>>::value);
static_assert(std::is_trivially_copy_constructible<WMutable<S<int>>>::value);
static_assert(std::is_trivially_move_constructible<WMutable<S<int>>>::value);
static_assert(std::is_trivially_copy_assignable<WMutable<S<int>>>::value);
static_assert(std::is_trivially_move_assignable<WMutable<S<int>>>::value);

static_assert(std::is_trivially_copyable<WMutable<SCtor<int>>>::value); // clang下报错
static_assert(std::is_trivially_copy_constructible<WMutable<SCtor<int>>>::value); // clang/gcc下报错
static_assert(std::is_trivially_move_constructible<WMutable<SCtor<int>>>::value);
static_assert(std::is_trivially_copy_assignable<WMutable<SCtor<int>>>::value);
static_assert(std::is_trivially_move_assignable<WMutable<SCtor<int>>>::value);

static_assert(std::is_trivially_copyable<WMutable<SCtorMutable<int>>>::value); // clang下报错
static_assert(std::is_trivially_copy_constructible<WMutable<SCtorMutable<int>>>::value); // clang/gcc下报错
static_assert(std::is_trivially_move_constructible<WMutable<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_copy_assignable<WMutable<SCtorMutable<int>>>::value);
static_assert(std::is_trivially_move_assignable<WMutable<SCtorMutable<int>>>::value);

static_assert(std::is_trivially_copyable<WMutable<SCtorDefault<int>>>::value); // clang下报错
static_assert(std::is_trivially_copy_constructible<WMutable<SCtorDefault<int>>>::value); // clang/gcc下报错
static_assert(std::is_trivially_move_constructible<WMutable<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_copy_assignable<WMutable<SCtorDefault<int>>>::value);
static_assert(std::is_trivially_move_assignable<WMutable<SCtorDefault<int>>>::value);

内容的提问来源于stack exchange,提问作者wanghan02

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:07:05