我正在尝试移植一个
int a[][]
从 Java 到 C++。我正在使用此类作为容器 ArrayRef对于整数,因为它处理引用,并且该项目广泛使用它。在我声明的 AbstractReader 类中
<code>const ArrayRef<int> START_END_PATTERN_;</code><br/>
<code>const ArrayRef<int> MIDDLE_PATTERN_;</code><br/>
<code>const ArrayRef<ArrayRef<int> > L_PATTERNS_;</code><br/>
<code>const ArrayRef<ArrayRef<int> > L_AND_G_PATTERNS_;</code><br/>
和
<code>static int START_END_PATTERN[];</code><br/>
<code>static int MIDDLE_PATTERN[];</code><br/>
<code>static int L_PATTERNS[10][4];</code><br/>
<code>static int L_AND_G_PATTERNS[20][4];</code><br/>
请注意结尾的下划线以区分这两个变量。
我不确定如何初始化二维 ArrayRef。我在这里发布的内容会出现段错误,因为那些 ArrayRefs 是在堆栈上分配的。谁有聪明的方法来做到这一点?
我实际设法让它工作的唯一方法是使用 ArrayRef< Ref<ArrayRef<int> > >
通过使 ArrayRef 继承自 Counted,这基本上是一个允许在 C++ 中进行引用计数的类。但是为了访问元素,我必须执行类似 *(foo[i])[j] 的操作,这比 foo[i][j] 稍微麻烦一些。
int AbstractReader::L\_AND\_G_PATTERNS[20][4] = {
{3, 2, 1, 1}, // 0
{2, 2, 2, 1}, // 1
{2, 1, 2, 2}, // 2
{1, 4, 1, 1}, // 3
{1, 1, 3, 2}, // 4
{1, 2, 3, 1}, // 5
{1, 1, 1, 4}, // 6
{1, 3, 1, 2}, // 7
{1, 2, 1, 3}, // 8
{3, 1, 1, 2}, // 9
// G patterns
{1, 1, 2, 3}, // 0
{1, 2, 2, 2}, // 1
{2, 2, 1, 2}, // 2
{1, 1, 4, 1}, // 3
{2, 3, 1, 1}, // 4
{1, 3, 2, 1}, // 5
{4, 1, 1, 1}, // 6
{2, 1, 3, 1}, // 7
{3, 1, 2, 1}, // 8
{2, 1, 1, 3} // 9
};
AbstractReader::AbstractReader()
: decodeRowStringBuffer_(ostringstream::app),
START_END_PATTERN_(START_END_PATTERN, 3),
MIDDLE_PATTERN_(MIDDLE_PATTERN, 5),
L_PATTERNS_(10),
L_AND_G_PATTERNS_(20) {
for (int i = 0; i < 20; i++) {
if (i < 10) {
L_PATTERNS_[i] = ArrayRef<int> ((L_PATTERNS[i]), 4);
}
ArrayRef<int> lgpattern((L_AND_G_PATTERNS[i]), 4);
L_AND_G_PATTERNS_[i] = lgpattern;
}
}
最佳答案
您所拥有的应该是安全的。 (堆栈分配)ArrayRef
s 创建分配的堆 Array
让我们支持他们,然后分享那些Array
编辑:感谢您发帖 Counted
.做了一些工作,但我想我知道发生了什么。
解决方案:不声明L_PATTERNS_
或 L_AND_G_PATTERNS_
作为const
.或者,const_cast
得到想要的operator[]
.例如
const_cast<ArrayRef<ArrayRef<int> > &>(L_PATTERNS_)[i] = ArrayRef<int> ((L_PATTERNS[i]), 4);
理由:
在 AbstractReader
,你声明:
const ArrayRef<ArrayRef<int> > L_PATTERNS_;
然后在它的构造函数中,你尝试赋值:
AbstractReader::AbstractReader() :
{
...
L_PATTERNS_[i] = ArrayRef<int> ((L_PATTERNS[i]), 4);
...
}
自 L_PATTERNS_
是const
, L_PATTERNS_[i]
从 ArrayRef<ArrayRef<int> >
调用一个方法:
T operator[](size_t i) const { return (*array_)[i]; }
这将返回 L_PATTERNS_[i]
处内容的全新拷贝.然后分配发生(进入临时),保持原始不变。当您稍后返回访问时 L_PATTERNS_[
xxx ]
,您正在查看原始的、未初始化的值(这是一个 NULL 引用/指针)。因此出现了段错误。
有点令人惊讶的是 ArrayRef
甚至允许这个任务。当然,它打破了“最小惊喜原则”。人们会期望编译器发出错误。为了确保编译器在未来更有帮助,我们需要对 ArrayRef
给出一个稍微不同的定义。的 operator[] const
(Array.h:121),如:
const T operator[](size_t i) const { return (*array_)[i]; }
或者可能(注意事项):
const T& operator[](size_t i) const { return (*array_)[i]; }
进行任何更改后,编译器都不允许分配。例如,GCC 报告:
error: passing 'const common::ArrayRef<int>' as 'this' argument of 'common::ArrayRef<T>& common::ArrayRef<T>::operator=(const common::ArrayRef<T>&) [with T = int]' discards qualifiers
关于c++ - 如何使用此特定容器在 C++ 中创建二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1367513/