如果禁用了异常,std :: vector <T>是否可以使用T的move构造函数?

格扎

如果std::vector<T>at的存储空间不足emplace_back(),则使用copy构造函数将元素复制到新的存储中,如果T的move构造函数不是noexcept该程序打印copy!godbolt):

#include <vector>
#include <cstdio>

struct T {
    T() = default;
    T(T &&) { printf("move!\n"); }
    T(const T &) { printf("copy!\n"); }
};

int main() {
    std::vector<T> v;
    v.emplace_back();
    v.emplace_back();
}

如果我用标记移动构造函数,则将noexcept打印此程序move!所有这些都是可以预期的。

现在,由于我不编写使用异常的代码,所以我使用来关闭异常-fno-exceptions而且我希望我的示例(没有noexcept)可以打印出来move!但是,GCC和clang仍然会打印copy!

该行为是否由标准规定?还是允许编译器使用move,只是没有针对这种情况进行优化?

ComicSansMS

标准没有说明关闭异常时会发生什么。ISO C ++是一种没有变体的单一语言,通过停用例外,您可以切换到标准不再涵盖的方言。

一个实现可以选择启用您要求的功能,但是这样做需要库实现付出更多的努力。对于标准的一致性实现,是否移动或复制的决定将基于std::is_­nothrow_­move_­constructible,该决定仅基于该决定基于noexcept移动构造函数签名中的说明符,而不取决于构造函数是否实际引发异常。为了实现您的期望,该实现必须为-fno-exceptions方言实现一种不同的检测机制,并将其作为非标准扩展名。

标准中的相关段落为[vector.modifiers]

template<class... Args> constexpr reference emplace_back(Args&&... args);

[...]如果在在端部插入单个元件的抛出异常,并且TCpp17CopyInsertableis_­nothrow_­move_­constructible_­v<T>true,没有影响。

即使不是很明显,这is_­nothrow_­move_­constructible_­v也会在false时强制调用副本构造函数,因为这是实现符合此要求的唯一方法。请注意,在该标准的早期版本中,情况更加微妙。C ++ 11草案仅说明:

如果non-的moveconstructor抛出异常CopyInsertable T,则效果未指定。

实际上是哪种行为与新措词具有相同的行为。

现在,从理论上讲,如果实现具有其他功能来检测函数是否除了查找之外noexcept(例如,通过对move构造函数的实现进行静态分析)是否可以抛出该函数,是否仍允许它在C ++ 11的措辞下移动?答案是肯定的,但是我不知道为实现如此良性的优化而付出的巨大努力。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从T *指针构造std :: vector <T>吗?

来自分类Dev

Emscripten 类构造函数采用 std::vector<T>

来自分类Dev

如果T对齐,std :: vector <T>也对齐吗?

来自分类Dev

我可以使用std :: vector <std :: vector <T >>表示C ++中的二维数组吗?

来自分类Dev

是否可以使用vector <T>作为值来定义unordered_map?

来自分类Dev

std :: vector <T> :: iterator可以简单地设为T *吗?

来自分类Dev

填充std :: vector时出现“ vector <T>太长”错误

来自分类Dev

是否可以让“命名构造函数”返回私有构造的,不可移动的,不可复制的std :: optional <T>?

来自分类Dev

用std :: vector <T *>控制内存

来自分类Dev

将 std::vector<T> 转换为 char *

来自分类Dev

如何将std :: vector <std :: reference_wrapper <T>>转换为std :: vector <T>

来自分类Dev

将std :: vector <T>函数应用于从std :: vector派生的类

来自分类Dev

从流中读取 std::vector<T> 的模板函数

来自分类Dev

C++:从 vector<vector<T>> 获取 T**

来自分类Dev

const std :: vector <T>和std :: vector <T> const有什么区别?

来自分类Dev

const std :: vector <T>和std :: vector <T> const有什么区别?

来自分类Dev

T-> std :: vector <T>的模板专业化

来自分类Dev

std :: vector <T> :: insert和std :: move_iterator <T>如何一起工作?

来自分类Dev

在Vector实现中如何正确使用std :: allocator <T>

来自分类Dev

为什么要在std :: vector :: push_back(T object)方法中构造对象时调用析构函数?

来自分类Dev

如何生成代码以使用自定义零值初始化std :: vector(如果它以T :: Zero形式存在)?

来自分类Dev

如何生成代码以使用自定义零值初始化std :: vector(如果它以T :: Zero形式存在)?

来自分类Dev

如何使用JNA将List <T>从Java传递到C ++ std :: vector函数参数

来自分类Dev

std :: vector <std :: array <T,N >>或std :: array <std :: vector <T>,N>类型的数组如何存储在内存中?

来自分类Dev

内部模板类型std :: vector <std :: vector <T >>的功能模板重载或特化

来自分类Dev

std :: vector <std :: vector <T >>的迭代器有效性

来自分类Dev

为什么std :: vector尽管声明为noexcept(false),但仍使用move构造函数

来自分类Dev

如果没有noexcept move构造函数,为什么带有std :: vector的代码不能编译却带有std :: unique_ptr的代码可以编译?

来自分类Dev

javaout typemap doesn't work for std::vector of pointers

Related 相关文章

  1. 1

    从T *指针构造std :: vector <T>吗?

  2. 2

    Emscripten 类构造函数采用 std::vector<T>

  3. 3

    如果T对齐,std :: vector <T>也对齐吗?

  4. 4

    我可以使用std :: vector <std :: vector <T >>表示C ++中的二维数组吗?

  5. 5

    是否可以使用vector <T>作为值来定义unordered_map?

  6. 6

    std :: vector <T> :: iterator可以简单地设为T *吗?

  7. 7

    填充std :: vector时出现“ vector <T>太长”错误

  8. 8

    是否可以让“命名构造函数”返回私有构造的,不可移动的,不可复制的std :: optional <T>?

  9. 9

    用std :: vector <T *>控制内存

  10. 10

    将 std::vector<T> 转换为 char *

  11. 11

    如何将std :: vector <std :: reference_wrapper <T>>转换为std :: vector <T>

  12. 12

    将std :: vector <T>函数应用于从std :: vector派生的类

  13. 13

    从流中读取 std::vector<T> 的模板函数

  14. 14

    C++:从 vector<vector<T>> 获取 T**

  15. 15

    const std :: vector <T>和std :: vector <T> const有什么区别?

  16. 16

    const std :: vector <T>和std :: vector <T> const有什么区别?

  17. 17

    T-> std :: vector <T>的模板专业化

  18. 18

    std :: vector <T> :: insert和std :: move_iterator <T>如何一起工作?

  19. 19

    在Vector实现中如何正确使用std :: allocator <T>

  20. 20

    为什么要在std :: vector :: push_back(T object)方法中构造对象时调用析构函数?

  21. 21

    如何生成代码以使用自定义零值初始化std :: vector(如果它以T :: Zero形式存在)?

  22. 22

    如何生成代码以使用自定义零值初始化std :: vector(如果它以T :: Zero形式存在)?

  23. 23

    如何使用JNA将List <T>从Java传递到C ++ std :: vector函数参数

  24. 24

    std :: vector <std :: array <T,N >>或std :: array <std :: vector <T>,N>类型的数组如何存储在内存中?

  25. 25

    内部模板类型std :: vector <std :: vector <T >>的功能模板重载或特化

  26. 26

    std :: vector <std :: vector <T >>的迭代器有效性

  27. 27

    为什么std :: vector尽管声明为noexcept(false),但仍使用move构造函数

  28. 28

    如果没有noexcept move构造函数,为什么带有std :: vector的代码不能编译却带有std :: unique_ptr的代码可以编译?

  29. 29

    javaout typemap doesn't work for std::vector of pointers

热门标签

归档