gpt4 book ai didi

c++ - std::is_nothrow_move_constructible 是否需要 noexcept 析构函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:37 24 4
gpt4 key购买 nike

以下代码无法使用 Visual Studio 2017 (15.5)、gcc 6.4.0 和 clang 4.0.1 进行编译,即静态断言失败:

struct Type
{
Type(Type&&) noexcept {}

~Type() noexcept(false) {}
};

static_assert(std::is_nothrow_move_constructible<Type>::value, "Type should be nothrow-move-constructible");
static_assert(std::is_nothrow_constructible<Type, Type&&>::value, "Type should be nothrow-constructible from Type&&");

这符合 C++ 标准吗? std::is_nothrow_move_constructible 是否需要 noexcept 析构函数?为什么?

如果我使用它,例如:

Type a;
Type b(std::move(a));

a 的析构函数在第二个语句中没有被调用。

最佳答案

我们可以看到 std::is_nothrow_move_constructible 是根据 is_­nothrow_­constructible_­v 定义的.所以这最终被 LWG issue 2116: is_nothrow_constructible and destructors 涵盖了尚未解决,因此它不是错误,除非问题的解决方式与当前实现方式不同。

它以以下讨论开始:

IMO if we specified is_[nothrow_]constructible in terms of a variable declaration whose validity requires destructibility, it is clearly a bug in our specification and a failure to realize the actual original intent. The specification should have been in terms of placement-new.

Daniel: At the time of the specification this was intended and the solution is not done by removing the destruction semantics of is_constructible.

The design of is_constructible was also impacted by the previous Constructible concept that explicitly contained destruction semantics, because during conceptification of the library it turned out to simplify the constraints in the library because you did not need to add Destructible all the time. It often was implied but never spoken out in C++03.

Pure construction semantics was considered as useful as well, so HasConstructor did also exist and would surely be useful as trait as well.

Another example that is often overlooked: This also affects wrapper types like pair, tuple, array that contain potentially more than one type: This is easy to understand if you think of T1 having a deleted destructor and T2 having a constructor that may throw: Obviously the compiler has potentially need to use the destructor of T1 in the constructor of std::pair to ensure that the core language requirements are satisfied (All previous fully constructed sub-objects must be destructed).

The core language also honors this fact in [class.copy] p11:

A defaulted copy/move constructor for a class X is defined as deleted (9.4.3 [dcl.fct.def.delete]) if X has:
[…]
— any direct or virtual base class or non-static data member of a type with a destructor that is deleted or inaccessible from the defaulted constructor,
[…]

戴夫:这尤其是关于 is_nothrow_constructible 的。事实 它因没有 noexcept dtor 而被挫败是一个缺陷。

结论是:

Ville would like "an evolution group" to take a look at this issue.

来自this gcc bug report至少 gcc 会等待问题得到解决。

另见 Non-trivial destructor make class non-trivially-constructible其中涵盖了对相关问题的其他一些引用。另请注意 clang bug for this .

关于c++ - std::is_nothrow_move_constructible 是否需要 noexcept 析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48186066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com