C++ 为什么这个初始值设定项列表在传递字符串时会使用行为不当?
我尝试了我的G++版本的C++0x初始值设定项列表实现,但它只输出空行C++ 为什么这个初始值设定项列表在传递字符串时会使用行为不当?,c++,c++11,iterator,stdinitializerlist,C++,C++11,Iterator,Stdinitializerlist,我尝试了我的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();
#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;
}
#包括
#包括
#包括
int main(){
std::初始值设定项\列表a({“hello”,“stackoverflow”});
对于(自动it=a.begin(),ite=a.end();it!=ite;++it)
标准::cout
代码:在上面的示例中,您似乎正在创建两个初始值设定项列表。临时的{“hello”,“stackoverflow”}
和std::initializer\u列表a
在gcc上,{}
初始值设定项列表实际上是临时数组,其生存期在完整语句后结束(除非直接绑定到std::initializer\u list
类似下面示例中注释行中的内容)
第一个列表的内部数组的生存期在a
的构造函数返回后立即结束,因此a
的数组现在指向无效内存(gcc仅复制指针)。您可以检查std::string
析构函数是否在进入循环之前被调用
当您进入循环时,您正在读取无效内存
根据最新标准草案(n3242),§18.9/1,初始值设定项列表甚至不能像那样复制(它们不提供带参数的构造函数)
@约翰内斯:如果删除c_str()
,它不会打印“hello”
:…我很困惑。它有什么问题?这是因为您使用的是局部变量引用(函数返回时它超出了范围)。当您使用c_str()时,您只是幸运(或者不幸运,取决于角度)内存仍然包含对char*
字符串的引用,并且堆区域尚未被覆盖。:)
std::initializer_list<std::string> a({"hello", "stackoverflow"});
std::initializer_list<std::string> a{"hello", "stackoverflow"}; //without ()
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;
#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;
}
dtor
dtor
after a's construction