unordered_set :: find和noexcept

时间:2015-12-17 16:03:35

标签: c++ c++11 unordered-set

我有以下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规范。

  • unordered_set :: find是否可以抛出?

我知道find并没有标记为noexcept,但实际上find不应该执行分配......

  • 从noexcept标记的函数调用find是否可以接受?

e.g:

const ArtifactImpl& foo() noexcept
{
  auto pos = artifactSet_.find(key);
  //etc...
}

尽管上面的foo()违背了发现的noexcept规范,但我想知道规范是否实际存在,如果一个人提供了自己的 noexcept 哈希和比较。

2 个答案:

答案 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。