为什么这个initializer_list在传递字符串时使用不当行为

Why does this initializer_list use misbehave when passing strings?

本文关键字:字符串 不当行为 initializer list 为什么      更新时间:2023-10-16

我尝试过G++版本的C++0x初始值设定项列表实现,但它只输出空行。

#include <initializer_list>
#include <iostream>
#include <string>
int main() {
  std::initializer_list<std::string> a({"hello", "stackoverflow"});
  for(auto it = a.begin(), ite = a.end(); it != ite; ++it)
    std::cout << *it << std::endl;
}

我不知道我做错了什么。有人能帮我吗?

在上面的示例中,您似乎正在创建两个初始值设定项列表。临时CCD_ 1和CCD_。

在gcc上,{}初始值设定项列表实际上是临时数组,其生存期在完整语句之后结束(除非像下面示例中注释行中那样直接绑定到std::initializer_list(。

第一个列表的内部数组的生存期在a的构造函数返回后立即结束,因此a的数组现在指向无效内存(gcc只复制指针(。您可以检查,在进入循环之前是否调用了std::string析构函数。

当你进入循环时,你正在读取无效的内存。

根据最新的标准草案(n3242(,§18.9/1,初始化器列表甚至不能像那样复制(它们不提供带参数的构造函数(。

#include <initializer_list>
#include <iostream>
class A
{
public:
  A(int)
  { }
  ~A()
  {
    std::cout << "dtor" << std::endl;
  }
};
int main()
{
  std::initializer_list<A> a({A(2), A(3)});
  // vs std::initializer_list<A> a{A(2), A(3)};
  std::cout << "after a's construction" << std::endl;
}

使用gcc 4.5.0,我得到

dtor
dtor
after a's construction
std::initializer_list<std::string> a({"hello", "stackoverflow"});

如果我声明为:

std::initializer_list<std::string> a{"hello", "stackoverflow"}; //without ()

那么它就起作用了:http://ideone.com/21mvL

但这很奇怪。看起来这是一个编译器错误。


编辑:

这无疑是一个编译器错误,因为如果我写(*it).c_str(),它会打印字符串!!

std::initializer_list<std::string> a({"hello", "stackoverflow"}); //with ()
for(auto it = a.begin(), ite = a.end(); it != ite; ++it)
   std::cout << (*it).c_str() << std::endl;

代码:http://ideone.com/hXr7V