C++ 如何在C++;使用此特定容器

C++ 如何在C++;使用此特定容器,c++,arrays,templates,constructor,class-template,C++,Arrays,Templates,Constructor,Class Template,我正在尝试移植一个 inta[][] 从java到C++。我使用这个类作为int的容器,因为它处理引用,并且项目广泛使用它。在AbstractReader类中,我声明 const ArrayRef START\u END\u PATTERN\u const-ArrayRef-MIDDLE\u模式 const ArrayRef L_PATTERNS const ArrayRef L_和_G_模式 及 static int START_END_模式[] static int MIDDLE_模式

我正在尝试移植一个
inta[][]

从java到C++。我使用这个类作为int的容器,因为它处理引用,并且项目广泛使用它。在AbstractReader类中,我声明


const ArrayRef START\u END\u PATTERN\u
const-ArrayRef-MIDDLE\u模式
const ArrayRef L_PATTERNS
const ArrayRef L_和_G_模式


static int START_END_模式[]
static int MIDDLE_模式[]
静态int L_模式[10][4]
静态int L_和u G_模式[20][4]
请注意尾部的下划线以区分这两个变量

我不确定如何初始化二维ArrayRef。我在这里发布的内容将是segfault,因为这些arrayref是在堆栈上分配的。有人有聪明的方法吗

< >我实际上是设法让它工作的,是使用ArrayRef的继承,从代码中使用<代码> ARRAYREF> REF> <代码>,这是一个允许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;
  }
 }
int AbstractReader::L\\ U和\\ U G\ U模式[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型
{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),
开始\结束\模式(开始\结束\模式,3),
中间模式(中间模式,5),
L_模式(10),
L_和G_模式(20){
对于(int i=0;i<20;i++){
如果(i<10){
L_-PATTERNS_[i]=ArrayRef((L_-PATTERNS[i]),4);
}
arrayreflgpattern((L_和G_模式[i]),4);
L_和G_模式u[i]=lgpattern;
}
}

你所拥有的应该是安全的。(堆栈分配)
ArrayRef
s创建堆分配
Array
s以支持它们,然后共享这些
Array
s

编辑:感谢您发布
已计数的
。做了点工作,但我想我知道发生了什么

解决方案:不要将
L\u模式
L\u和\u G\u模式
声明为
const
。或者,
const\u cast
以获得所需的
运算符[]
。例如

const_cast<ArrayRef<ArrayRef<int> > &>(L_PATTERNS_)[i] = ArrayRef<int> ((L_PATTERNS[i]), 4);
然后在其构造函数中,尝试赋值:

AbstractReader::AbstractReader() :
{
    ...
    L_PATTERNS_[i] = ArrayRef<int> ((L_PATTERNS[i]), 4);
    ...
}
这将返回位于
L\u PATTERNS\ui]
的全新副本。然后,分配发生(变成临时分配),保持原始分配不变。当您稍后返回访问
L\u PATTERNS.[
xxx
]
时,您看到的是原始的未初始化值(这是一个空引用/指针)。因此,赛格断层

有些令人惊讶的是,
ArrayRef
甚至允许这个赋值。当然,这违反了“最小惊喜原则”。人们会期望编译器发出错误。为了确保编译器在将来更有用,我们需要对
ArrayRef
运算符[]const
(Array.h:121)给出稍微不同的定义,例如:

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
错误:将'const common::ArrayRef'作为'common::ArrayRef&common::ArrayRef::operator=(const common::ArrayRef&)[with T=int]的'this'参数传递将丢弃限定符

原因可能有多种。例如,在粘贴中不包含“Counted”类,并且在某个点上调用->retain()(第130行)。这个方法没有显示。

我是这么想的,但由于某种原因,如果在循环之后我尝试访问内部阵列,它们就会出现故障。它给了我一个执行错误的访问权限或类似的权限。我知道为什么了。这是
ArrayRef
Managu中的一个微妙缺陷,非常感谢您对该问题的详细检查和出色解释。我错误地认为,即使它是一个常量,如果我在构造函数列表中以及以后在构造函数中初始化它,我仍然能够修改它。奇怪的是,编译器不会抱怨它!我尝试了const_cast,但出现以下错误:
error:common::ArrayRef类型的const_cast使用无效,它不是指针、引用,也没有指向数据成员类型的指针
我也尝试将签名更改为第一个版本,但结果如下:错误:将“const common::ArrayRef”作为“common::ArrayRef&common::ArrayRef::operator=(const common::ArrayRef&)[with T=int]的“this”参数传递'discards qualifiers`我认为这里的问题是,即使它返回一个const对象,它也会尝试在赋值中修改它,因此L_PATTERNS_I[I]实际上不会被赋值。在我看来,唯一的方法是制作L_图案非常量。。。以后有没有办法把它扔给一个警察。现在没有足够的资源来检查它,但我认为在
const\u cast
中添加一个“&”将修复我的解决方案。至于第二个错误——这就是我们的意图。答案更改为包含此信息。
const T operator[](size_t i) const { return (*array_)[i]; }
const T& operator[](size_t i) const { return (*array_)[i]; }
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