用户发布了answer,其中写着:
因此,请参考
Hash
void topWords(Hash const& t, std::string const& word, std::string* topA);
另外,
string[]
不是C ++中的类型- ...
提问者发布的原始功能如下:
void topWords(Hash t, string word, string topA[]);
我知道在Java中,声明数组的语法是:
int[] anArray;
而在C ++中它是:
int anArray[someNumber];
我怀疑这是回答者所指的,但也许他们意味着别的东西。所以我咨询了n3337:
格式化注释:省略了无关的内容,为了便于阅读添加了新行
§8.3.4[dcl.array]
1在声明
T D
中,D
的格式为D1 [常量表达式 opt ] 属性说明符-SEQ <子>选择子>
和声明
T D1
中的标识符类型是 “ derived-declarator-type-listT
”,然后是标识符的类型D
的数组类型;...
T
称为数组元素类型;...
如果存在常量表达式(5.19),则它应为a 积分常数表达式及其值应大于零。 常量表达式指定 的边界(元素数量) in)数组。如果常量表达式的值为
N
,则为。{ 数组有N
个元素编号为0
到N-1
,以及类型 D的标识符是“{em> derived-declarator-type-list array ofN T
”。...
除非另有说明,否则如果省略常量表达式,则为类型
D
的标识符是“ derived-declarator-type-list 数组 未知的T
“范围,一个不完整的对象类型。类型 “{em> derived-declarator-type-listN T
”数组是一种不同的类型 来自类型“ derived-declarator-type-list 未知边界的数组T
“,见3.9。...
所以anArray
应该是someNumber int
的数组。 topA
调整为pointer to std::string
。我的理解在哪里失败?
为了避免使当前答案无效,我会将其作为更新发布。你们当中有些人似乎误解了我的问题的本质。我不是在询问Java vs C ++,也不是数组与指针,而是从语言律师的角度来看,为什么string[]
不会被视为类型。
如果我们看一下§3.9/ 6:
...数组对象的声明类型可能是未知数组 大小因此在翻译单元中的某一点不完整 并在以后完成;这两个点的数组类型(“数组的数组
T
“的未知范围和”N T
“的数组是不同的类型。 ...... [ 示例:的extern int arr[]; // the type of array is incomplete
所以arr
显然有一个类型。
答案 0 :(得分:4)
您的理解似乎大多是正确的 - 因为topA
是一个形式参数,其类型会从array of T
调整为pointer to T
。同样,anArray
将是someNumber int的数组。
对于它的价值,在有限的情况下你可以在C ++中使用空括号并且仍然有一个数组,而不是一个指针。最常见的是extern
声明,如:
extern int anArray[];
...将anArray
声明为一个int数组,其数量在指定的位置指定。
如果有人以声明为string topA[]
的参数开头,那么在大多数情况下,编译器会将其调整为string *topA
,但, you < / em>可能希望将其更改为:std::vector<std::string> &topA
(或std::vector<std::string> const &topA
,如果您不打算修改数组的内容。)
答案 1 :(得分:4)
string[]
是一个不完整的数组类型。
可以完成不完整的数组类型:
C ++11§3.9/ 6 :
“ 声明的数组对象类型可能是一个未知大小的数组,因此在某一点上是不完整的 在翻译单位,稍后完成;这两个点的数组类型(“T
未知范围的数组”和“N
T
数组”是不同的类型。
通常会发生类似
的声明extern int x[];
在某个标题中,然后在实现文件中
int x[42];
除了因未知长度而不完整外,由于项目类型不完整,数组类型可能不完整。
struct Blah;
extern Blah x[42];
auto main() -> int {}
但是,这不允许void
。
顺便说一下,值得一提的是unique_ptr<T>
与unique_ptr<T[]>
不同。后者在其支持的转换中受到限制。这是因为如果将指针转换为类型为T
的数组,指向类型为T_base
或T_derived
的数组的指针,则为项目大小可能不同,从而导致索引(以及其他许多内容)。
答案 2 :(得分:2)
如果你继续阅读§8.3.4,我们会得到这一段(大胆强调我的):
数组类型的对象包含一个连续分配的非空N类型的子对象。 类型“ derived-declarator-type-list NT”数组与类型“ derived-declarator-type的类型不同-list 数组 未知的T 界限“,见3.9。任何类型的形式“ cv-qualifier-seq N T数组”都调整为“数组” N cv-qualifier-seq T“,类似于”T的未知界限数组“和”T的运行时界限数组“。 可选的 attribute-specifier-seq 属于数组。
举例:
typedef int A[5], AA[2][3];
typedef const A CA; // type is “array of 5 const int”
由于标准提到了数组类型,并且显示了一个清楚地表明变量类型是数组的例子,我认为这足以证明数组通常是一种类型。这是一种奇怪的类型,不像其他基本类型那样好玩,但它仍然是一种类型。该段特别提到“T的未知界限”类型,也就是你的string[]
。
答案 3 :(得分:2)
extern int arr[]; // the type of array is incomplete
所以arr显然有一个类型。
arr
有一个类型。这不会使int[]
成为完整类型。 arr
具有不完整的类型,直到定义了数组维度(可能在另一个TU中)。
[...] D的标识符的类型是“T的未知边界的derived-declarator-type-list数组”,不完整的对象类型
在此之前参考arr
的具体类型(例如使用sizeof
)将会出错。
答案 4 :(得分:0)
string[]
是一种类型,但它是一种误导性的;你不能只复制string[]s
并希望它能做你想做的事。它本质上是写string *
的另一种方式。
如果您想要一个可以传递的string
数组,请使用std::vector<std::string>
(按值)或boost::shared_array<std::string>
(按引用)或类似名称。 boost::shared_array
可能最接近您对Java数组类型的期望。