我有以下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_;
请注意,我的散列和谓词模板参数/ s具有noexcept规范。
我知道find并没有标记为noexcept,但实际上find不应该执行分配......
e.g:
const ArtifactImpl& foo() noexcept
{
auto pos = artifactSet_.find(key);
//etc...
}
尽管上面的foo()违背了发现的noexcept规范,但我想知道规范是否实际存在,如果一个人提供了自己的 noexcept 哈希和比较。
答案 0 :(得分:1)
如果您抛出函数(它必须调用)抛出它可能会抛出。仅仅因为这个原因,我不会使用它。但更重要的是,我不会使用noexcept
说明符,因为它违反了find
函数&#39; s规格。
答案 1 :(得分:1)
tl; dr: noexcept
似乎仅对移动构造函数/赋值运算符有用。
如果你敢接受cplusplus.com甚至我作为足够的权限:它不会抛出任何异常,除非方面如此 - 例如分配器或比较器抛出,没有任何东西抛出。
(我现在应该去挖掘相关的ISO段落......)
但是,就我的理解而言,noexcept
在这里并不特别有用:
Andrzej has a detailed explanation on his blog,我(错)引用相关部分:
noexcept
如果实施方案尽管有规范对于某些函数,例如
vector<T>::push_back
使用T
的移动构造函数/赋值而不是复制构造函数/赋值可以显着提高性能。但是,如果此移动构造函数/赋值可能会抛出,push_back
将失去强大的异常安全保证。为了利用移动操作(在可能的情况下)并同时保持强有力的保证,需要有一种方法来确定给定的移动操作是否可能抛出,并使用它或者替代地退回好老复制。这正是函数std::move_if_noexcept
的作用,但它需要在适当的时候将T的操作标记为noexcept。