目前可用的std::dyarray的任何替代方案
Any alternative to std::dynarray presently available?
C++11为我们提供了出色的std::array
,它需要在编译时知道大小:
std::array<int, 3> myarray = {1, 2, 3};
现在,我碰巧有一些旧的short*
缓冲区要包装,其大小仅在运行时是已知的(当然也是已知的)。
C++14将定义std::dynarray
来覆盖这种情况,但dynarray
在GCC 4.7和Clang 3.2中都不可用。
那么,有人知道一个容器可以与std::array
相媲美(在效率方面),但在编译时不需要指定大小吗?我怀疑Boost已经为我准备好了什么,尽管我什么都找不到。
在dynarray
可用之前,我认为std::vector
就是您想要的。只需使用分配构造函数或reserve
,就可以避免重新分配开销。
如果您不需要std::dynarray<T>::at()
提供的范围检查访问,我将投票支持std::unique_ptr<short[]>(new short[n])
。您甚至可以使用初始值设定项列表:
#include <iostream>
#include <memory>
int main(int argc, char** argv) {
const size_t n = 3;
std::unique_ptr<short[]> myarray(new short[n]{ 1, 2, 3 });
for (size_t i = 0; i < n; ++i)
std::cout << myarray[i] << 'n';
}
您可以(ab)使用std::valarray<short>
。
int main() {
short* raw_array = (short*) malloc(12 * sizeof(short));
size_t length = 12;
for (size_t i = 0; i < length; ++ i) {
raw_array[i] = (short) i;
}
// ...
std::valarray<short> dyn_array (raw_array, length);
for (short elem : dyn_array) {
std::cout << elem << std::endl;
}
// ...
free(raw_array);
}
valarray
支持dynarray
的大多数功能,除了:
- 分配器
- 反向迭代器
.at()
.data()
请注意,标准(自n3690起)不要求valarray
存储是连续的,尽管没有理由不这样做:)。
(对于一些实现细节,在libstdc++中,它被实现为(length,data)对,而在libc++中则实现为(begin,end)。)
缓冲区和大小,再加上一些基本方法,可以满足您的大部分需求。
很多样板,但有这样的东西:
template<typename T>
struct fixed_buffer {
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
std::size_t length;
std::unique_ptr<T[]> buffer;
std::size_t size() const { return length; }
iterator begin() { return data(); }
const_iterator begin() const { return data(); }
const_iterator cbegin() const { return data(); }
iterator end() { return data()+size(); }
const_iterator end() const { return data()+size(); }
const_iterator cend() const { return data()+size(); }
reverse_iterator rbegin() { return {end()}; }
const_reverse_iterator rbegin() const { return {end()}; }
const_reverse_iterator crbegin() const { return {end()}; }
reverse_iterator rend() { return {begin()}; }
const_reverse_iterator rend() const { return {begin()}; }
const_reverse_iterator crend() const { return {begin()}; }
T& front() { return *begin(); }
T const& front() const { return *begin(); }
T& back() { return *(begin()+size()-1); }
T const& back() const { return *(begin()+size()-1); }
T* data() { return buffer.get(); }
T const* data() const { return buffer.get(); }
T& operator[]( std::size_t i ) { return data()[i]; }
T const& operator[]( std::size_t i ) const { return data()[i]; }
fixed_buffer& operator=(fixed_buffer &&) = default;
fixed_buffer(fixed_buffer &&) = default;
explicit fixed_buffer(std::size_t N):length(N), buffer( new T[length] ) {}
fixed_buffer():length(0), buffer() {}
fixed_buffer(fixed_buffer const& o):length(o.N), buffer( new T[length] )
{
std::copy( o.begin(), o.end(), begin() );
}
fixed_buffer& operator=(fixed_buffer const& o)
{
std::unique_ptr<T[]> tmp( new T[o.length] );
std::copy( o.begin(), o.end(), tmp.get() );
length = o.length;
buffer = std::move(tmp);
return *this;
}
};
缺少at()
,分配器也是。
operator=
不同于dyn_array
提案——提案阻止了operator=
,我赋予它值语义。一些方法效率较低(如copy
构造)。我允许空fixed_buffer
。
这可能会阻碍使用堆栈存储dyn_array
,这可能是它不允许的原因。如果你想要接近dyn_array的行为,只需删除我的operator=
和琐碎的构造函数。
C++14还添加了可变长度数组,类似于C99中的数组,这已经得到了一些编译器的支持:
void foo(int n) {
int data[n];
// ...
}
它不是一个容器,因为它不支持begin()
和end()
等,但可能是一个可行的解决方案。
dynarray
在没有堆栈分配组件的情况下很容易实现——这显然要到或者C++14才能实现——所以我只是将dynarray
反向后台端口(forwardport?)作为我的库的一部分,并从那以后开始使用它。到目前为止,它在C++03中工作,没有任何"Nebraska中的无效"条款,因为它不完全依赖于任何C++11特定的功能,并且有
是很好的这样,当C++1y/2z dynarray
出现时,我的代码在很大程度上仍然是兼容的。
(这也是许多显而易见的"为什么C++没有早点拥有它?"事情之一,所以有它在身边很好)。
这是在我了解到显然C++1y-dynarray
和C++1y运行时大小数组是完全相同的提议(一个只是另一个的语法糖),而不是我最初认为的两个不同但互补的提议之前。因此,如果我现在必须解决同样的问题,我可能会为了正确起见,切换到基于@Yakk的解决方案。
- 我想使用 "cout" 命令慢慢打印文本,但我真的找不到任何解决方案
- 透视视图的任何解决方案 openGL qt.
- 如何计算该程序的复杂性?是否有任何其他复杂性较低的解决方案
- 如果找不到解决方案,我如何留下递归循环,而不会打印任何东西
- STXXL的任何STXXL替代方案都可以在编译时处理未知大小或任何技巧
- C++字符串代码点和代码单元的任何良好解决方案
- C++ getline(cin,变量)行为不端.网站上没有任何解决方案有帮助
- 是否有任何好的解决方案可以解决C 中两个类之间的交叉引用
- 有任何替代SHGetKnownFolderPath的Windows XP用户令牌的方案吗
- Strchr不起作用,或者我需要一个替代方案来检查给定字符串中的任何字符是否是另一个字符串的一部分
- 在任何情况下都会出现意外输出.我的解决方案出了什么问题
- 函数指针的通用映射.有可能吗?任何替代方案
- 有没有一种方法可以在不重建任何项目的情况下重新链接解决方案
- C++/C# 解决方案中不可用的任何 CPU
- 任何解压缩向量以在C++中函数参数的解决方案
- C++:单向跳转到函数.任何替代方案
- 寻找继承/多态性替代方案的任何理由
- 在c++中,任何更好的方法都可以做到这一点,计算谜题的解决方案(49!结果,49个循环)
- 目前可用的std::dyarray的任何替代方案
- c++编写和读取文本文件是非常缓慢的,任何替代方案