#include

问题描述 投票:0回答:1
)失败了

注意

[unique.ptr]
不能保证
std::unique_ptr

是标准的,但是人们期望它包含一个单个T*,从本质上讲,它可以保证它是

标准布局类Type.

这是一个已知的问题,归结为
GCC错误104419
LLVM问题53021。 我们可以将其作为GCC错误写出,因为GCC在这里不合规。 简而 std::unique_ptr

c++ clang unique-ptr libstdc++ c++23
1个回答
0
投票
std::tuple

的情况下),并且template <typename T, typename Deleter = empty> struct unique_ptr { private: tuple<T*, Deleter> data; }; 用于避免浪费在空类上的任何字节。 从历史上看,这是通过依靠EBO(空基础优化), 但是由于使用libstdc ++ 11,因此使用了std::deleter 会产生一些实施差异。

小型可重现示例

there是一个最小的复制品,取自Jonathan Wakely的错误报告,并进行了稍作调整(

Https://godbolt.org/z/xke4r7h71
):
std::tuple

只有clang失败了标记的断言,GCC都通过了所有的主张。
删除
[[no_unique_address]]

使两个编译器的断言失败。

哪个编译器是正确的
这是GCC错误。
从本质上讲,
#include <type_traits> template<typename T, bool = __is_empty(T)> struct node; template<typename T> struct node<T, true> { [[no_unique_address]] T t; }; template<typename T> struct node<T, false> { T t; }; template<typename... T> struct tuple; template<typename T> struct tuple<T> : node<T> { }; template<typename T, typename U> struct tuple<T, U> : tuple<U>, node<T> { }; struct empty {}; static_assert( sizeof(tuple<int, empty>) == sizeof(int), "" ); static_assert( __is_standard_layout(tuple<int>), ""); static_assert( __is_standard_layout(tuple<empty>), ""); static_assert( __is_standard_layout(tuple<int, empty>), ""); // Clang fails template <typename T, typename Deleter = empty> struct unique_ptr { tuple<T*, Deleter> data; }; static_assert( __is_standard_layout(tuple<int, empty>)); // Clang fails static_assert( __is_standard_layout(unique_ptr<int>)); // Clang fails
不应该对类别是否是标准的标准层有任何影响,但GCC认为,使用此属性“删除”一个子对象会绕过[class.prop]段2.6
段:

[如果该类是标准级别,则在同一班级中首先在同一类中声明的所有非静态数据成员和基础类别,并且[...]

A
// Clang fails

将在不同的基类中首先声明数据成员,这通常会使一类失去标准级别的资格。

	
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.