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

GCC与Clang对Wrapper<MoveOnly>的std::is_trivially_copyable判定分歧谁正确?

编译器分歧:Wrapper<MoveOnly>是否属于平凡可拷贝类型?

首先定义仅可移动类型MoveOnly:

struct MoveOnly
{
    MoveOnly()  = default;
    ~MoveOnly() = default;

    MoveOnly(const MoveOnly&)            = delete;
    MoveOnly& operator=(const MoveOnly&) = delete;

    MoveOnly(MoveOnly&&) noexcept            = default;
    MoveOnly& operator=(MoveOnly&&) noexcept = default;
};

GCC与Clang对该类型的特性判定完全一致:

static_assert(not std::is_trivially_copy_constructible_v<MoveOnly>);
static_assert(not std::is_copy_constructible_v<MoveOnly>);
static_assert(    std::is_trivially_copyable_v<MoveOnly>);

接下来定义一个传播平凡拷贝构造性的包装器模板Wrapper:

template <typename T>
struct Wrapper
{
    Wrapper(const Wrapper&)
        requires(!std::is_trivially_copy_constructible_v<T> && std::is_copy_constructible_v<T>)
    {
    }

    Wrapper(const Wrapper&)
        requires(std::is_trivially_copy_constructible_v<T>) = default;
};

对于Wrapper<MoveOnly>,GCC与Clang在以下两个断言上达成一致:

static_assert(not std::is_trivially_copy_constructible_v<Wrapper<MoveOnly>>);
static_assert(not std::is_copy_constructible_v<Wrapper<MoveOnly>>);

但二者在平凡可拷贝特性的判定上出现分歧:

static_assert(    std::is_trivially_copyable_v<Wrapper<MoveOnly>>);
    // GCC编译通过,Clang编译失败

正确判定:Clang的结果符合C++标准

核心依据:C++标准的特殊成员函数规则与平凡可拷贝定义

根据C++标准,一个类型要成为平凡可拷贝(trivially copyable),必须同时满足:

  1. 析构函数是平凡的;
  2. 至少存在一个非删除的拷贝构造函数、移动构造函数、拷贝赋值运算符或移动赋值运算符;
  3. 所有非删除的上述特殊成员函数都是平凡的。

针对Wrapper<MoveOnly>:

  • 拷贝构造函数:用户声明的两个重载均因约束条件不满足被排除,因此Wrapper<MoveOnly>的拷贝构造函数被视为删除状态。
  • 移动构造/赋值、拷贝赋值运算符:由于用户显式声明了拷贝构造函数(即使是带约束的重载),编译器不会隐式生成这些特殊成员函数,它们同样被视为删除状态。
  • 析构函数:未被用户声明,属于平凡析构,满足第一条要求,但第二条的必要条件(存在非删除的特殊成员函数)未被满足。

综上,Wrapper<MoveOnly>没有任何可用的非删除拷贝/移动构造或赋值运算符,不符合平凡可拷贝类型的定义,因此Clang的判定是正确的;GCC的错误在于,误将约束不满足的用户声明拷贝构造函数视为“未声明”,错误允许编译器隐式生成移动构造函数,进而错误判定其为平凡可拷贝类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:17:04