std::vector 的自包含、STL 兼容实现
Visual Studio 2010 及早期版本附带的 std::vector
实现有一个众所周知的特殊性:resize
方法具有以下签名(符合 C++03 标准) ):
void resize(size_type new_size, value_type value);
而不是早在 C++11 之前就被大多数其他 STL 实现(如 gcc 的 STL 或 STLport)使用的符合 C++11 的签名:
void resize(size_type new_size, const value_type& value);
第一个变体的问题是,在某些情况下,它会失败如果 value_type
具有对齐规范,则进行编译:
struct __declspec(align(64)) S { ... };
std::vector<S> v; // error C2719: '_Val': formal parameter with __declspec(align('64')) won't be aligned
这是一个 好吧 已知问题,除了使用不同的 std::vector
实现之外,没有令人满意的解决方法。
我正在寻找一个编写良好、经过充分测试、独立且与 STL 兼容的 std::vector
实现,并具有 MIT 风格的许可证,我可以作为对齐类型的首选容器放入我的项目中。
我考虑过从 STLport 或 gcc 的 STL 中提取它,但由于完全符合标准,它们都很大,并且有许多重要的依赖项。
(我对 std::vector 的合理子集的实现非常满意,该子集仅支持 push_back
、clear
、容量
、大小
、保留
、调整大小
、交换
和数组索引。)
有什么想法吗?
The implementation of std::vector
that ships with Visual Studio 2010 and earlier versions has a well known particularity: the resize
method has the following signature (C++03-compliant):
void resize(size_type new_size, value_type value);
instead of the C++11-compliant signature that's been used by the majority of other STL implementations (like gcc's STL or STLport) long before C++11:
void resize(size_type new_size, const value_type& value);
The problem with the first variant is that, in some situations, it will fail to compile if value_type
has an alignment specification:
struct __declspec(align(64)) S { ... };
std::vector<S> v; // error C2719: '_Val': formal parameter with __declspec(align('64')) won't be aligned
This is a well known problem with no satisfactory workaround apart from using a different implementation of std::vector
.
I'm looking for a well-written, well-tested, self-contained and STL-compatible implementation of std::vector
with a MIT-style licence that I could drop into my project as a container of choice for aligned types.
I considered extracting it from STLport or gcc's STL but, being fully standard-compliant, they're both large with many non-trivial dependencies.
(I would be perfectly happy with an implementation of a reasonable subset of std::vector
that would only support push_back
, clear
, capacity
, size
, reserve
, resize
, swap
and array indexing.)
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Eigen 库背后的人似乎找到了一个很好的解决方法来解决存储“过度对齐类型”的问题(Stephan T. Lavavej 称之为)
std::vector
在 Visual Studio 的 STL 中实现。他们的实现似乎不必要的复杂(检查来源此处和此处),但主要思想是封装进入 < 的类型code>std::vector 带有一个薄包装器:
关于 Eigen 中的实现,我必须承认我不太明白
Eigen::aligned_allocator_indirection
,EIGEN_WORKAROUND_MSVC_STL_SUPPORT
中对算术类型进行例外处理,Eigen::workaround_msvc_stl_support 中定义所有这些构造函数和运算符
,resize
用于Eigen::aligned_allocator_indirection
分配器的std::vector
...欢迎提供线索。关键是,这个技巧非常有效(据我所知),除了稍微不雅之外,我没有发现它有任何问题。
The guys behind the Eigen library seem to have found a nice workaround for the problem of storing "overly-aligned types" (as Stephan T. Lavavej call them) into a
std::vector
as implemented in Visual Studio's STL.Their implementation seems unnecessary complicated (check the sources here and here) but the main idea is to encapsulate the type that goes into the
std::vector
with a thin wrapper:About the implementation in Eigen, I must admit I don't quite understand
Eigen::aligned_allocator_indirection
,EIGEN_WORKAROUND_MSVC_STL_SUPPORT
,Eigen::workaround_msvc_stl_support
,resize
in their partial specialization ofstd::vector
for theEigen::aligned_allocator_indirection
allocator...Clues welcome. The point is, this trick works perfectly (as far as I can tell) and I don't see anything wrong with it, apart maybe from the slight inelegance.
最简单(也是最好的,恕我直言)的选择是提供一个免费函数作为向量接口的扩展,它做了正确的事情。您需要实现
resize
的函数都可以从std::vector
的公共接口中获得:并且为了保持一致性,还有单参数版本:
但是,如果您只想要插入新向量并且不必担心自由或成员函数,另一种选择是简单地子类化 std::vector :
请注意,我还提供了 resize 的单参数版本code>,因为两个参数版本将隐藏所有基类版本。另请注意,我需要在所有成员函数调用前加上
this->
前缀,因为它们依赖于基类std::vector
,因此也依赖于模板论据。The easiest (and best, imho) option would be to provide a free function as an extension to the
vector
interface, which does the right thing. The functions you need to implementresize
are all available from the public interface ofstd::vector
:And for consistency also the single argument version:
If you, however, just want to drop-in the new vector and never worry about free or member function, another option is to simply subclass
std::vector
:Note that I also provided the single argument version of
resize
, since the two argument version would hide all base-class versions. Also note that I needed to prefix all member function calls withthis->
, since they are dependent on the base classstd::vector
, and as such on the template arguments.