Ori*_*ent 1 c++ containers stl aggregate c++17
如何在(例如)STL容器中引入聚合初始化的支持以正确构建它们?我的意思是:
struct A { int i; char c; };
std::list< A > l; // empty
l.insert(std::memberwise, 1, '2');
// <=> l.insert({1, '2'});
Run Code Online (Sandbox Code Playgroud)
std::memberwise
是一个可能的标签,就像在STL中已经存在一样std::piecewise_construct
,std::allocator_arg
等等.
从理论上讲,以这种方式扩展STL容器是否可行?有没有最好的方法("STL-way")来做到这一点?它看起来怎么样?
问题是关于界面设计和(内部)实现的可能性(不是细节).
我确定容器使用::new (static_cast< void * >(pstorage) value_type(std::forward< Args >(args)...);
内部的东西.我确定,用括号替换括号会破坏更改.因为非缩小,例如
l.insert({1, '2'});
评论中一般提到可能会导致过度移动value_type
.很可能这一步将由任何现代编译器优化,但无论哪种方式都有过多的花括号.
你应该使用emplace
-style结构.标准库容器将这种结构转发到allocator_traits<Alloc>::construct<T>
,这预计是一种可变功能.如果Alloc
没有construct
成员函数,那么allocator_traits::construct
只需使用()
初始化语法的placement new .
显然,这不允许你通过聚合初始化emplace
.但是,您可以通过提供自己的分配器来有效地实现LWG 2089建议的解决方案std::allocator
,该分配器可能来自,具有自己的construct
方法.你construct
应该只new(p) T(...)
在is_constructible<T, ...>::value
真实的情况下使用.如果不是,那么你使用new(p) T{...}
.
在C++ 17中,这实际上并不难写:
template< class U, class... Args >
void construct( U* p, Args&&... args )
{
if constexpr(std::is_constructible_v<U, Args...>)
::new((void*)p) U(std::forward<Args>(args)...);
else
::new((void*)p) U{std::forward<Args>(args)...};
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
94 次 |
最近记录: |