9

我已经尝试了我的 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;
}

我不知道我做错了什么。谁能帮帮我?

4

2 回答 2

3

看起来您在上面的示例中创建了两个初始化列表。临时{"hello", "stackoverflow"}std::initializer_list<std::string> a

在 gcc 上,{}初始化列表实际上是临时数组,其生命周期在完整语句之后结束(除非std::initializer_list在下面示例中的注释行中直接绑定到 like)。

第一个列表的内部数组的生命周期在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
于 2011-04-09T19:37:32.563 回答
1
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

于 2011-04-09T13:44:37.447 回答