使用 requires 的可选非平凡析构函数

Posted

技术标签:

【中文标题】使用 requires 的可选非平凡析构函数【英文标题】:Optional non-trivial destructor using requires 【发布时间】:2022-01-23 18:11:18 【问题描述】:

使用 C++ 20 要求声明可选的非平凡析构函数的正确方法是什么?对于复制构造函数和移动构造函数,我可以先声明非平凡的需要复制/移动构造函数,然后是默认声明,但对于析构函数,我得到了奇怪的行为:

#include <string>
#include <type_traits>

template<typename T>
concept TriviallyDestructible = std::is_trivially_destructible_v<T>;
template<typename T>
concept NotTriviallyDestructible = !TriviallyDestructible<T>;

template<typename T>
struct OptionalDestructor

    T value;

    ~OptionalDestructor() requires NotTriviallyDestructible<T>
    

    
    ~OptionalDestructor() = default;
;


int main()

    static_assert(TriviallyDestructible<OptionalDestructor<int>>);
    static_assert(!TriviallyDestructible<OptionalDestructor<std::string>>);

没有为我在 clang 主干上编译,而

#include <string>
#include <type_traits>

template<typename T>
concept TriviallyDestructible = std::is_trivially_destructible_v<T>;
template<typename T>
concept NotTriviallyDestructible = !TriviallyDestructible<T>;

template<typename T>
struct OptionalDestructor

    T value;

    ~OptionalDestructor() = default;
    ~OptionalDestructor() requires NotTriviallyDestructible<T>
    

    
;


int main()

    static_assert(TriviallyDestructible<OptionalDestructor<int>>);
    static_assert(!TriviallyDestructible<OptionalDestructor<std::string>>);

正在按照我期望的方式进行编译。在苹果铿锵声中,我根本无法编译可选的析构函数,并且 MSVC 有不同的行为,再次考虑订单...... 哪个编译器在这里表现正确?

https://godbolt.org/z/Tvjo9e4nx

GCC 似乎可以编译这两个命令。

【问题讨论】:

【参考方案1】:

GCC 是正确的。顺序应该无关紧要。

Clang documentation 表示它尚未实现P0848,这将使您的示例编译。令我惊讶的是,Clang 确实以一种顺序编译示例而不是另一种顺序,并且 MSVC 的行为相似,但我猜他们只是查看第一个预期的析构函数。

【讨论】:

以上是关于使用 requires 的可选非平凡析构函数的主要内容,如果未能解决你的问题,请参考以下文章

C++ 虚拟析构函数 (virtual destructor)

从 C++ 中的析构函数中恢复对象?

多态和抽象

CPP游戏攻略03

在调用析构函数之前对象的生命周期已经结束?

类与其动态内存分配