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

Optional non-trivial destructor using requires

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

#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 trunk 上编译,而

#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>>);
}

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

https://godbolt.org/z/Tvjo9e4nx

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

海湾合作委员会是正确的。顺序应该无关紧要。

Clang documentation indicates that it hasn't yet implemented P0848,这将使您的示例编译。令我惊讶的是,Clang 确实按一个顺序而不是另一个顺序编译示例,并且 MSVC 的行为相似,但我猜他们只看第一个预期的析构函数。