unordered_set::find 和 noexcept
unordered_set::find and noexcept
我有以下 unordered_set:
class ArtifactImpl{...};
class ArtifactSetKeyOps
{
public:
std::size_t operator()(const ArtifactImpl& artifact) const noexcept;
bool operator()(const ArtifactImpl& lhs, const ArtifactImpl& rhs) const noexcept;
};
std::unordered_set<ArtifactImpl,
ArtifactSetKeyOps,ArtifactSetKeyOps> artifactSet_;
请注意,我的散列和谓词模板 argument/s 有一个 noexcept 规范。
- unordered_set::find可以投吗?
我知道 find 没有标记为 noexcept,但实际上 find 不应该执行分配...
- 从标记为 noexcept 的函数中调用 find 是否可以接受?
例如:
const ArtifactImpl& foo() noexcept
{
auto pos = artifactSet_.find(key);
//etc...
}
尽管上面的 foo() 违背了 find 的 noexcept 规范,但我想知道该规范是否实际上有效,前提是提供了自己的 noexcept 哈希和比较。
如果您的散列函数(它必须调用)抛出,它可能会抛出。仅出于这个原因,我不会使用它。 但更重要的是,我不会使用 noexcept
说明符,因为它违反了 find
函数的规范。
tl;dr: noexcept
似乎只对 move constructor/assignment 运算符有用。
如果你敢于接受 cplusplus.com 甚至我作为足够的权威:它不会抛出任何异常,除非一个方面抛出 - 例如分配器或比较器抛出,什么都不抛出。
(我现在应该去挖掘相关的ISO段落了……)
然而,据我了解,noexcept
在这里不是特别有用:
Andrzej has a detailed explanation on his blog,我在这里(误)引用了相关部分:
noexcept
如果实施抛出尽管规范 也没什么用
- 它无助于实现不抛出异常的安全保证
- 并且不太可能启用重大优化,除非在一种情况下与移动语义相关:
for certain functions, like vector<T>::push_back
using move constructors/assignments of T
instead of copy constructors/assignments can dramatically increase performance. However, if this move constructor/assignment can potentially throw, push_back
would loose the strong exception safety guarantee. In order to take an advantage of the move operations (where possible) and at the same time keep the strong guarantee, there needs to be a way to determine if a given move operation is potentially throwing or not, and use it or alternatively fall back to good old copying. This is exactly what function std::move_if_noexcept
does, but it needs T’s operations to be marked as noexcept where appropriate.
我有以下 unordered_set:
class ArtifactImpl{...};
class ArtifactSetKeyOps
{
public:
std::size_t operator()(const ArtifactImpl& artifact) const noexcept;
bool operator()(const ArtifactImpl& lhs, const ArtifactImpl& rhs) const noexcept;
};
std::unordered_set<ArtifactImpl,
ArtifactSetKeyOps,ArtifactSetKeyOps> artifactSet_;
请注意,我的散列和谓词模板 argument/s 有一个 noexcept 规范。
- unordered_set::find可以投吗?
我知道 find 没有标记为 noexcept,但实际上 find 不应该执行分配...
- 从标记为 noexcept 的函数中调用 find 是否可以接受?
例如:
const ArtifactImpl& foo() noexcept
{
auto pos = artifactSet_.find(key);
//etc...
}
尽管上面的 foo() 违背了 find 的 noexcept 规范,但我想知道该规范是否实际上有效,前提是提供了自己的 noexcept 哈希和比较。
如果您的散列函数(它必须调用)抛出,它可能会抛出。仅出于这个原因,我不会使用它。 但更重要的是,我不会使用 noexcept
说明符,因为它违反了 find
函数的规范。
tl;dr: noexcept
似乎只对 move constructor/assignment 运算符有用。
如果你敢于接受 cplusplus.com 甚至我作为足够的权威:它不会抛出任何异常,除非一个方面抛出 - 例如分配器或比较器抛出,什么都不抛出。
(我现在应该去挖掘相关的ISO段落了……)
然而,据我了解,noexcept
在这里不是特别有用:
Andrzej has a detailed explanation on his blog,我在这里(误)引用了相关部分:
noexcept
如果实施抛出尽管规范 也没什么用
- 它无助于实现不抛出异常的安全保证
- 并且不太可能启用重大优化,除非在一种情况下与移动语义相关:
for certain functions, like
vector<T>::push_back
using move constructors/assignments ofT
instead of copy constructors/assignments can dramatically increase performance. However, if this move constructor/assignment can potentially throw,push_back
would loose the strong exception safety guarantee. In order to take an advantage of the move operations (where possible) and at the same time keep the strong guarantee, there needs to be a way to determine if a given move operation is potentially throwing or not, and use it or alternatively fall back to good old copying. This is exactly what functionstd::move_if_noexcept
does, but it needs T’s operations to be marked as noexcept where appropriate.