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

Clang的is_trivially_copyable对该案例的判定是否存在错误?

确认Clang对std::is_trivially_copyable_v的判定是否为Bug

我在为个人项目实现兼容C++20的Optional类型时遇到了如下问题:

#include <type_traits>

template <class T>
struct Optional
{
    constexpr Optional() = default;

    constexpr Optional(const Optional &) requires std::is_trivially_copy_constructible_v<T>
    = default;

    constexpr Optional(const Optional &other) requires(!std::is_trivially_copy_constructible_v<T>)
        : m_payload(other.m_payload.x)
    {
    }

  private:
    union Payload
    {
        T x;
    } m_payload;
};

// 全部通过
static_assert(std::is_trivially_copy_constructible_v<Optional<int>>);
static_assert(std::is_trivially_copy_assignable_v<Optional<int>>);
static_assert(std::is_trivially_destructible_v<Optional<int>>);

// 在Clang-15.0.0及多个旧版本中失败
static_assert(std::is_trivially_copyable_v<Optional<int>>);

针对Optional<int>,前三个static_assert都能通过,但最后一个检查std::is_trivially_copyable_v在Clang 15.0.0及更早版本中失败,而GCC和MSVC的判定符合预期。

分析

根据C++标准,std::is_trivially_copyable的核心要求是:

  • 类的所有符合条件的拷贝构造函数、移动构造函数、拷贝赋值运算符、移动赋值运算符都必须是平凡的;
  • 类的析构函数也必须是平凡的。

对于Optional<int>,由于std::is_trivially_copy_constructible_v<int>为true,第二个拷贝构造函数的约束!std::is_trivially_copy_constructible_v<T>不满足,因此该构造函数不会成为Optional<int>的候选成员函数。此时Optional<int>仅拥有默认的平凡拷贝构造函数,同时析构函数、赋值运算符也都是平凡的,完全符合std::is_trivially_copyable的判定条件。

Clang旧版本错误地将未满足约束的拷贝构造函数也纳入了std::is_trivially_copyable的检查范围,导致错误判定Optional<int>不是平凡可拷贝类型。

结论

这确实是Clang的已知Bug,在Clang 16及后续版本中已经修复,GCC和MSVC的判定行为符合C++标准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:45:37