如果标准指定它具有析构函数,class 是否应该不可破坏?
Should class be not trivially destructible, if standard specifies that it has a destructor?
考虑 std::latch
[thread.latch.class]:
namespace std {
class latch {
public:
static constexpr ptrdiff_t max() noexcept;
constexpr explicit latch(ptrdiff_t expected);
~latch();
latch(const latch&) = delete;
latch& operator=(const latch&) = delete;
void count_down(ptrdiff_t update = 1);
bool try_wait() const noexcept;
void wait() const;
void arrive_and_wait(ptrdiff_t update = 1);
private:
ptrdiff_t counter; // exposition only
};
}
请注意存在析构函数。这意味着这应该成立:
static_assert(std::is_trivially_destructible_v<std::latch> == false);
然而,它是相反的实现(MSVC STL,libstdc++,libc++):https://godbolt.org/z/6s8173zTc
这是:
- 实现自由(实现是正确的,
is_trivially_destructible_v
可能是true
或false
)
- 每个实现中的实现缺陷(实现应该具有
std::latch
的非平凡析构函数)
- 标准缺陷(标准不应该指定
std::latch
具有非平凡的析构函数)
?
这是实施自由。 C++ 标准定义了 class,class 的实现已经实现了。
有一些 classes 标准明确要求一个普通的析构函数。例如,如果一个现有的 class 是平凡可破坏的,那么它的 std::optional
也是 must be 平凡可破坏的。这个需要说明一下。
因此,除非某处明确声明 class 是或不是平凡可构造的,否则这取决于实现(如果可能)。
查看gcc的头文件:它不仅声明,而且明确定义了析构函数:
~latch() = default;
基于此,编译器可以计算出整个事物是微不足道的可破坏的。
考虑 std::latch
[thread.latch.class]:
namespace std {
class latch {
public:
static constexpr ptrdiff_t max() noexcept;
constexpr explicit latch(ptrdiff_t expected);
~latch();
latch(const latch&) = delete;
latch& operator=(const latch&) = delete;
void count_down(ptrdiff_t update = 1);
bool try_wait() const noexcept;
void wait() const;
void arrive_and_wait(ptrdiff_t update = 1);
private:
ptrdiff_t counter; // exposition only
};
}
请注意存在析构函数。这意味着这应该成立:
static_assert(std::is_trivially_destructible_v<std::latch> == false);
然而,它是相反的实现(MSVC STL,libstdc++,libc++):https://godbolt.org/z/6s8173zTc
这是:
- 实现自由(实现是正确的,
is_trivially_destructible_v
可能是true
或false
) - 每个实现中的实现缺陷(实现应该具有
std::latch
的非平凡析构函数) - 标准缺陷(标准不应该指定
std::latch
具有非平凡的析构函数)
?
这是实施自由。 C++ 标准定义了 class,class 的实现已经实现了。
有一些 classes 标准明确要求一个普通的析构函数。例如,如果一个现有的 class 是平凡可破坏的,那么它的 std::optional
也是 must be 平凡可破坏的。这个需要说明一下。
因此,除非某处明确声明 class 是或不是平凡可构造的,否则这取决于实现(如果可能)。
查看gcc的头文件:它不仅声明,而且明确定义了析构函数:
~latch() = default;
基于此,编译器可以计算出整个事物是微不足道的可破坏的。