- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
据我了解, move 构造函数和 move 赋值必须标记为 noexcept,以便编译器在例如在 vector 内部重新分配时使用它们。
但是,是否存在 move 分配、 move 构造可能实际抛出的真实案例?
更新:
例如,在构造时具有分配资源的类不能是不可抛出的。
最佳答案
However, is there any real-world case where a move-assign, move-construct (or swap) might actually throw?
是的。考虑 std::list
的实现. end
迭代器必须指向列表中的“最后一个元素”。存在 std::list
的实现哪里什么end
指向的是一个动态分配的节点。即使是默认构造函数也会分配这样一个节点,以便在您调用 end()
时, 有一点可以指出。
在这样的实现中,每个 构造函数都必须为end()
分配一个节点。指向……甚至 move 构造函数。该分配可能会失败,并引发异常。
同样的行为可以扩展到任何基于节点的容器。
这些基于节点的容器的实现也进行了“短字符串”优化:它们将结束节点嵌入容器类本身,而不是动态分配。因此默认构造函数(和 move 构造函数)不需要分配任何东西。
move 赋值运算符可以抛出任何 container<X>
如果是容器的分配器 propagate_on_container_move_assignment::value
为 false,并且如果 lhs 中的分配器不等于 rhs 中的分配器。在那种情况下, move 赋值运算符被禁止将内存所有权从 rhs 转移到 lhs。如果您使用 std::allocator
,则不会发生这种情况,作为 std::allocator
的所有实例彼此相等。
更新
这是一个符合条件且可移植的示例,说明了 propagate_on_container_move_assignment::value
时的情况。是假的。它已经针对最新版本的 VS、gcc 和 clang 进行了测试。
#include <cassert>
#include <cstddef>
#include <iostream>
#include <vector>
template <class T>
class allocator
{
int id_;
public:
using value_type = T;
allocator(int id) noexcept : id_(id) {}
template <class U> allocator(allocator<U> const& u) noexcept : id_(u.id_) {}
value_type*
allocate(std::size_t n)
{
return static_cast<value_type*>(::operator new (n*sizeof(value_type)));
}
void
deallocate(value_type* p, std::size_t) noexcept
{
::operator delete(p);
}
template <class U, class V>
friend
bool
operator==(allocator<U> const& x, allocator<V> const& y) noexcept
{
return x.id_ == y.id_;
}
};
template <class T, class U>
bool
operator!=(allocator<T> const& x, allocator<U> const& y) noexcept
{
return !(x == y);
}
template <class T> using vector = std::vector<T, allocator<T>>;
struct A
{
static bool time_to_throw;
A() = default;
A(const A&) {if (time_to_throw) throw 1;}
A& operator=(const A&) {if (time_to_throw) throw 1; return *this;}
};
bool A::time_to_throw = false;
int
main()
{
vector<A> v1(5, A{}, allocator<A>{1});
vector<A> v2(allocator<A>{2});
v2 = std::move(v1);
try
{
A::time_to_throw = true;
v1 = std::move(v2);
assert(false);
}
catch (int i)
{
std::cout << i << '\n';
}
}
这个程序输出:
1
表示vector<T, A>
move 赋值运算符在 propagate_on_container_move_assignment::value
时复制/move 其元素是 false 并且两个有问题的分配器不比较相等。如果这些拷贝/move 中的任何一个抛出,则容器 move 分配抛出。
关于c++ - move 哪个 throw ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19833258/
我一直认为“throw”和“throw ex”的区别was that throw alone wasn't resetting the stacktrace of the exception. 不幸的
我需要处理这样的api错误代码,并为某些状态代码抛出错误。但是遵循代码显示了以上错误。我怎样才能做到这一点? func login(data: [String: Any], completion: @
我见过在 JavaScript 中抛出错误的 3 种不同方式: throw 'message'; throw Error('message'); throw new Error('message');
这个问题在这里已经有了答案: Exception handling : throw, throws and Throwable (8 个答案) 关闭 10 年前。 谁能简单介绍一下Java异常处理中
这是我的代码: func loadData() { ref.child(currentUserID!).observe(.childAdded) { (snapshot) in
可能很明显,但是我仍然无法理解throw和rethrow之间的区别,什么时候应该使用它们中的任何一个? 最佳答案 根据Effective Dart: If you decide to rethrow
这个问题在这里已经有了答案: "new" keyword in Scala (3 个答案) 关闭 5 年前。 在 Scala 中进行一些函数式编程,并且来自 Java 背景,我倾向于像这样抛出异常:
我有一个验证输入字符串的代码,如果输入字符串与所需的格式不匹配,我需要抛出 IllegalArgumentException,有多个字段,每个字段都有一组不同的验证条件,因此对于当前我正在执行的每个字
我的方法有一个抛出 NullPointerException 的返回类型。 public class Student { public String studentOne() {
有些帖子询问这两者之间的区别。 (为什么我要提这个...) 但我的问题在某种程度上有所不同,我在另一个错误神级处理方法中调用了“throw ex”。 public class Program {
谁能解释一下 throw、throws 和 Throwable 之间的区别以及何时使用哪个? 最佳答案 throws :在编写方法时使用,声明有问题的方法抛出了指定的(检查的)异常。 与检查的异常相反
我想知道编写异常收件箱和发件箱是否会改变特定程序的行为,例如 抛出 MyException(); 和 抛出(我的异常()); 我的代码: #include #include using names
抛出异常时,保留堆栈跟踪是最常见的期望行为,在 Java 中,这可以通过 throw ex; 获得,但在 C# 中,throw; 必须使用。 (另请注意,许多 C# 程序员经常错误地使用 throw
这个问题在这里已经有了答案: Exception handling : throw, throws and Throwable (8 个答案) 关闭 8 年前。 谁能举个例子说清楚Java异常处理中
这两个有什么区别吗? 最佳答案 异常是针对程序逻辑中的错误。 JVM 使用错误来表示环境有问题,例如 OutOfMemoryError 或 IncompatibleClassChangeError。
我试图到处寻找这个问题的答案,但似乎我运气不好。 我有一个非常简单的 Mongoose 模型 var userObject = { profile: { username: {
我遇到了这个重新抛出的异常,我很惊讶它甚至可以编译。 } catch(SomeException e) { ... throw(e); } 这个throw()和平时用的有什么区别吗?.
想象两段相似的代码: try { [...] } catch (myErr &err) { err.append("More info added to error..."); throw
我试图弄清楚Java中方法签名中的抛出和抛出语句之间的区别。方法签名中的抛出如下: public void aMethod() throws IOException{ FileReader f
这个问题在这里已经有了答案: throw Error('msg') vs throw new Error('msg') (2 个回答) 24 天前关闭。 没有 new 时抛出错误有什么缺点吗?关键词?
我是一名优秀的程序员,十分优秀!