for (auto x : {exp1,exp2,exp3}) ?

A

Andrew Tomazos

Is the following valid C++11? Im getting a seg fault on it from gcc
4.6.1.

#include <set>
#include <string>
#include <iostream>

using namespace std;

int main()
{
set<string> ss;
ss.insert("a");
ss.insert("b");
ss.insert("c");

for (auto s1 : ss)
for (auto s2 : {s1 + "x", s1 + "y", s1 + "z"} )
cout << s2 << endl;

return 0;
}
 
J

Juha Nieminen

Andrew Tomazos said:
set<string> ss;
ss.insert("a");
ss.insert("b");
ss.insert("c");

for (auto s1 : ss)
for (auto s2 : {s1 + "x", s1 + "y", s1 + "z"} )
cout << s2 << endl;

I must admit that I don't know enough C++11 to tell for sure, but
I'd imagine that the type of 's2' resolves to an initializer list
containing std::string *references*, which point to temporary objects
that are destroyed by the time the body of the loop is executed the
first time. (This would be very different when eg. constructing a
vector with such an initializer list, because the temporaries would
be destroyed only after the constructor call ends.)

I may be completely wrong, though, because at this juncture I really
don't know what the type of '{ s1 + "x" }' is.
 
A

Andrew Tomazos

  I must admit that I don't know enough C++11 to tell for sure, but
I'd imagine that the type of 's2' resolves to an initializer list
containing std::string *references*, which point to temporary objects
that are destroyed by the time the body of the loop is executed the
first time. (This would be very different when eg. constructing a
vector with such an initializer list, because the temporaries would
be destroyed only after the constructor call ends.)

  I may be completely wrong, though, because at this juncture I really
don't know what the type of '{ s1 + "x" }' is.

I think you're right, the seg fault is a memcpy of string in invalid
memory.

When I make the following change...

-                for (auto s2 : {s1 + "x", s1 + "y", s1 + "z"} )
+                for (auto s2 : set<string> {s1 + "x", s1 +"y", s1 +
"z"} )

....it works. I suspect this constructs a temporary set<string> that
holds the expressions in the init list in memory for the lifetime of
the loop.

I'm still partially confused why the initializer_list<string> doesn't
do this itself. I guess it needs to be a list of rvalue references in
order to do its other magic.
-Andrew.
 
M

Marc

Andrew said:
Is the following valid C++11? Im getting a seg fault on it from gcc
4.6.1.

g++-4.6 executes the destructors before starting the loop.
g++-4.7 executes them at the end of the loop and is happy with the code.
It seems more likely that g++-4.7 is right :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top