22

我可以使用数组创建一个命名变量,如下所示:

char s[] = {1, 2, 3, 0};
if (strcmp(s, t))
    ...

但是以下不起作用:

if (strcmp(char[]{1,2,3,0}, t))
    ...

有没有办法用初始化列表指定一个临时的未命名数组?(在这种情况下,字符串文字可以工作,但对于 char 数组以外的数组?)

更新:

#include <iostream>
#include <cstring>

using namespace std;

typedef char CA[];

int main()
{
        cout << CA{1,2,3, 0} << endl;
}

给出error: taking address of temporary array( g++-4.7.2 -std=gnu++11)

更新 2:

我认为(也许)正在发生的事情是字符串文字被特别祝福为lvalues,但是临时数组是prvalues,因此您不能获取它们的地址。不过,这是一个疯狂的猜测,我不确定。

更新 3:

其实我认为这应该是错误的:

“NT 数组”或“T 的未知边界数组”类型的左值或右值可以转换为“指向 T 的指针”类型的纯右值。结果是指向数组第一个元素的指针。

4

3 回答 3

15

1)我受这个问题困扰了一段时间。编译以下程序,g++ 4.7.1 (tdm64-1) 给出错误:“teste1.cpp:6:33: error:taking address of temporary array”

#include <iostream>
#include <cstring>
using namespace std;
int main()
{ char t[]={1,2,3,0};
  if (strcmp((char[]){1,2,3,0},t)==0)  //error
    cout << "equal\n";
  else 
    cout << "different\n";
}

但是,如果添加关键字“const”,错误消失,程序运行顺利:

if (strcmp((const char[]){1,2,3,0},t)==0) //correct

2) 在某些情况下,仅仅添加关键字“const”可能还不够。例如,g++ 4.7.1 在编译以下程序时给出“错误:获取临时数组的地址”:

#include <iostream>
#include <cstring>
using namespace std;

void f(char* p)
{ for (int i=0; p[i]!=0; i++) 
    cout << int(p[i]) << " ";
  cout << endl;
}

int main() {
  f((char[]){1,2,3,0}); // error
}

如果添加关键字“const”,编译器会给出另一种错误:“从 'const char*' 到 'char*' [-fpermissive] 的无效转换”:

f((const char[]){1,2,3,0}); //error

要成功编译程序,您可以使用选项“-fpermissive”编译它或进行显式类型转换:

f((char*)(const char[]){1,2,3,0}); // correct
于 2013-08-10T14:46:22.080 回答
6

是的,使用 typedef 然后说

ArrayType{1, 2, 3, 0}

或者使用别名模板,然后

AliasTemplate<char[]>{1, 2, 3, 0}
于 2013-03-17T08:26:42.973 回答
4

看来这个问题可以用C++11“move”来解决。在 g++ 4.8.1 中编译程序:

#include <iostream>
#include <cstring>
using namespace std;

typedef char CA[];
int main() {
  cout << CA{'a','b','c',0} << endl;
}

导致“错误:获取临时数组的地址”。但是,使用“移动”:

cout << move(CA{'a','b','c',0}) << endl;

程序编译并正确运行。必须调用编译器才能使用 C++11 方言:

g++ prog1.cpp -o prog.exe -std=c++11

相似地,

#include <iostream>
#include <cstring>
using namespace std;
int main()
{ char t[]={1,2,3,0};
  if (strcmp( move((char[]){1,2,3,0}) ,t)==0)  //OK
    cout << "equal\n";
  else 
    cout << "different\n";
}

也可以使用 -std=c++11 标志正确编译和运行。

于 2014-11-06T18:06:01.197 回答