为什么根据 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?
考虑以下最小示例:
// 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.9
和clang 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
我以前使用过这个(没有意识到我的不合格代码)来存储种子的副本以用于日志记录。*
我想知道:
为什么
seed_seq
不可复制?这是我第一次遇到
g++
和clang
不符合标准。偏离标准是一个有意识的决定,还是一个实现错误?这种情况有多普遍?我想了解更多。
*我意识到我对seed_seq
的想法是错误的,如果我只对seed_seq::param
值(seed_seeq
的初始种子值)感兴趣,那么我应该把我的副本保存在vector<T>
中,而不是一个用来生成整数的类型。
根据T.C.和ecatmur,对于那些将来看到这一点的人来说,这是libstdc++错误65631。虽然没有预计到达时间;行为符合最初的提议,但根据N3037的论文,这一提议被修改为从概念中删除可复制性,以解决LWG问题1069。
相关文章:
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 为什么默认复制函数在按值发送参数时不调用?
- 为什么调用复制构造函数而不是移动构造函数?
- 简单可复制与可简单复制
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- shared_ptr删除器类 - 为什么要复制删除器?
- 对于参加可复制和可移动类的访问者来说,应该有多少过载?
- 可变参数宏:无法通过"..."传递非平凡可复制类型的对象
- 为什么调用复制构造函数来构造空unique_ptr向量?
- 为什么 std::atomic<std::string> 会给出微不足道的可复制错误?
- 为什么一对常量是微不足道的可复制的,而对不是?
- 为什么 std::function 本身是可复制构造的类型?
- 为什么Boost.Asio处理程序必须是可复制的
- 为什么shared_ptr删除器必须是可复制的
- 为什么要求自定义分配器是可复制的
- 为什么向量中的元素需要是可复制的
- 为什么boost::equals要求范围是可复制的?
- 为什么持有引用可复制的类
- 为什么普通的可复制类要求析构函数必须是普通的