为什么根据 C++11 标准,std::seed_seq是不可复制的,为什么 gcc/clang 不符合?

Why is std::seed_seq non-copyable according to C++11, and why doesn't gcc/clang conform?

本文关键字:为什么 可复制 不符合 gcc clang C++11 标准 std seq seed      更新时间:2023-10-16

考虑以下最小示例:

// main.cpp
#include <random>
int main(int, char **)
{
  std::seed_seq seed1{1337, 42};
  std::seed_seq seed2(seed1);
  std::seed_seq seed3 = seed2;
  return 0;
}

根据C++标准,这不应该编译,因为std::seed_seq既不可复制构造,也不可复制赋值。

然而,这与g++ 4.9clang 3.4 都可以很好地编译

g++-4.9 -std=c++11 -Wall main.cpp
clang++ -std=c++11 -Wall main.cpp

android ndk的llvm-libc++实现似乎遵循了seed_seq的"不可复制"属性。可以在的来源中确认

 android-ndk-r10d/sources/cxx-stl/llvm-libc++/libcxx/include/random:3553

或者通过使用编译最小示例

 ${NDK_HOME}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ 
 -std=c++11 -c -Wall 
 -I${NDK_HOME}/sources/cxx-stl/llvm-libc++/libcxx/include 
 -I${NDK_HOME}/sources/cxx-stl/llvm-libc++/../llvm-libc++abi/libcxxabi/include 
 -I${NDK_HOME}/sources/cxx-stl/llvm-libc++/../../android/support/include 
 -isystem ${NDK_HOME}/platforms/android-18/arch-arm/usr/include 
 main.cpp

我以前使用过这个(没有意识到我的不合格代码)来存储种子的副本以用于日志记录。*

我想知道:

  1. 为什么seed_seq不可复制?

  2. 这是我第一次遇到g++clang不符合标准。偏离标准是一个有意识的决定,还是一个实现错误?这种情况有多普遍?我想了解更多。


*我意识到我对seed_seq的想法是错误的,如果我只对seed_seq::param值(seed_seeq的初始种子值)感兴趣,那么我应该把我的副本保存在vector<T>中,而不是一个用来生成整数的类型。

根据T.C.和ecatmur,对于那些将来看到这一点的人来说,这是libstdc++错误65631。虽然没有预计到达时间;行为符合最初的提议,但根据N3037的论文,这一提议被修改为从概念中删除可复制性,以解决LWG问题1069。