【问题标题】:Determinism in C++ standard libraryC++ 标准库中的确定性
【发布时间】:2021-04-03 15:21:29
【问题描述】:

std::sort 不保证稳定。

它是否保证是确定性的?

例如,这段代码是否总是打印1

struct S
{
    int a, b;
};

bool cmp(const S& lhs, const S& rhs)
{
    return lhs.a < rhs.a;
}

int main()
{
    std::vector<S> seq1 = {{1, 2}, {1, 3}};
    std::vector<S> seq2 = seq1;
    std::sort(seq1.begin(), seq1.end(), cmp);
    std::sort(seq2.begin(), seq2.end(), cmp);
    std::cout << (seq1.back().b == seq2.back().b) << '\n';
}

此外,C++ 标准库通常是否具有确定性(除了明显不确定的元素,如 RNG 和时钟)?

【问题讨论】:

  • 我不相信标准可以保证这种确定性。据我所知,它对这个问题保持沉默,因此实施不需要是确定性的。
  • 事实上,对于核心语言,它明确说明了相反的情况(可能在非规范性注释中;我懒得查)——大意是,在一个表达式中与f() + g() 一样,两个函数调用的顺序是未指定的,而且在此表达式的两次求值之间不必相同。
  • 没有这样的保证。使用stable_sort 是安全的。
  • 不稳定的一个可能原因是如果在地下使用线程。

标签: c++ stl deterministic


【解决方案1】:

使用std::sort 对范围进行排序后,对范围的唯一要求是元素根据提供的谓词进行排序。因此,如果有多个可能的有效排序,那么只要生成其中任何一个,实现就符合要求。

每次在同一范围内调用std::sort 时,允许实现生成不同的排序。它还可以在程序每次执行时产生不同的排序。

这是std::sort 上的requirements。请注意,没有提到每次结果范围都相同的任何要求,因此不能保证结果是确定性的。

【讨论】:

  • 请链接源,我会接受这个答案。
  • @Phastasm 我已链接到标准页面。没有具体的措辞说它是“非确定性的”,但我认为这可以从缺乏“确定性”的保证中推断出来。
  • 如果需要更多,还有 stable_sort。
  • @SornelHaetir 稳定性和确定性并不相同,可能只需要确定性,就像问题中的代码一样。
  • @SornelHaetir 这实际上并不能证明排序是非确定性的。虽然保证确定性没有稳定性会很奇怪,但正如 Phastasm 指出的那样,这是可能的。
猜你喜欢
  • 2016-06-12
  • 2013-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
  • 2011-06-16
  • 2011-06-25
相关资源
最近更新 更多