[Assign] list_of comma operator removed?

I recently attempted to upgrade from boost 1.32.0 to boost 1.33.1 got received some compiler errors from boost.assign. My most common usage of boost::assign looks like this: vector<string> data = (list_of<string>(), "foo", "bar", "baz"); I like this better than the alternative syntax (elements delimeted by parentheses) because I can type it more quickly and it more closely resembles array initialization syntax, which makes it more likely that my coworkers, who aren't as familiar with boost, will understand what's going on. But it appears my compiler errors were caused by the removal of the comma operator in the class the list_of function returns. It appears this was intentional since the unit tests were changed, but the current documentation for list_of still indicates the comma operator is legal syntax, and operator+= still uses the comma syntax, so I'm a little confused. I remember there was some discussion on this list earlier about the comma operator and whether it is ever ok to overload it, but I couldn't find anything about actually removing it from any aspect of boost.assign in the mailing list, the documentation, or the version history. Maybe I haven't looked deeply enough yet? Was the comma operator intentionally removed from list_of? If so, I would like to understand why so I can be properly dissuaded from reintroducing it for my own use. Thanks, -- Jon Willesen

Jon Willesen wrote:
I recently attempted to upgrade from boost 1.32.0 to boost 1.33.1 got received some compiler errors from boost.assign.
My most common usage of boost::assign looks like this:
vector<string> data = (list_of<string>(), "foo", "bar", "baz");
I like this better than the alternative syntax (elements delimeted by parentheses) because I can type it more quickly and it more closely resembles array initialization syntax, which makes it more likely that my coworkers, who aren't as familiar with boost, will understand what's going on.
ok.
But it appears my compiler errors were caused by the removal of the comma operator in the class the list_of function returns. It appears this was intentional since the unit tests were changed, but the current documentation for list_of still indicates the comma operator is legal syntax, and operator+= still uses the comma syntax, so I'm a little confused.
My memory is weak in this respect, but I think I might have viewed the syntax as redundant. If you like the comma, you might write data += "foo", "bar", "baz"; but that is not initialization. I don't mind adding the operator again, it should be trivially defined, but I wonder if we removed it because it could actually create problems in some situations. -Thorsten

Thorsten Ottosen wrote:
Jon Willesen wrote:
But it appears my compiler errors were caused by the removal of the comma operator in the class the list_of function returns. It appears this was intentional since the unit tests were changed, but the current documentation for list_of still indicates the comma operator is legal syntax, and operator+= still uses the comma syntax, so I'm a little confused.
My memory is weak in this respect, but I think I might have viewed the syntax as redundant.
Well, yes. But since I find the comma syntax more useful/convenient, the redundancy has a sufficient reason to exist IMO.
If you like the comma, you might write
data += "foo", "bar", "baz";
but that is not initialization.
Right - I often need to initialize global constants or complex data structures, so the += syntax won't always work for me.
I don't mind adding the operator again, it should be trivially defined, but I wonder if we removed it because it could actually create problems in some situations.
It seems to me that most arguments against overloading the comma operator would also apply to the += context. Here are a couple of threads I found on the topic: (http://tinyurl.com/7dg5m), and (http://tinyurl.com/9b2va). Do either of those jog your memory? Can anyone else come up with other examples? Neither objection seems sufficient to me to remove operator,. Lack of sequencing doesn't bother me because I'm clearly asking for initialization by calling list_of and should not expect sequencing. As for the second link, (list_of<int>(), (1, 2, 3)) looks sufficiently silly to me to dismiss. The only other thing I can think of that concerns me at all is if I'm trying to call a function that has been overloaded to take 1..N arguments using the preprocessor library or some other code generator. Then this code: func(list_of<string>(), "foo", "bar", "baz"); might compile successfully and pass four arguments to func when I really meant to pass one argument: func((list_of<string>(), "foo", "bar", "baz")); This particular combination of advanced techniques seems unlikely enough that I would still rather have the comma operator. Given no other objections, I would vote to have list_of's comma operator reinstated. -- Jon

Jon Willesen wrote:
Thorsten Ottosen wrote:
The only other thing I can think of that concerns me at all is if I'm trying to call a function that has been overloaded to take 1..N arguments using the preprocessor library or some other code generator. Then this code:
func(list_of<string>(), "foo", "bar", "baz");
might compile successfully and pass four arguments to func when I really meant to pass one argument:
func((list_of<string>(), "foo", "bar", "baz"));
I think was the motivation. I had a user that called a constructor: cons( list_of(3)(5), 4, 5 ); he wanted to pass 3 arguments, but only one was passed. I haven't tried it, but is adding parathesis enough to pass the three arguments forward?
This particular combination of advanced techniques seems unlikely enough that I would still rather have the comma operator. Given no other objections, I would vote to have list_of's comma operator reinstated.
Requiring paranthesis in certain contexts seems like a very subtle thing to do. I like easy syntax, but I also think surprising and subtle behavior can be a pain for users. -Thorsten

Jon Willesen wrote:
The only other thing I can think of that concerns me at all is if I'm trying to call a function that has been overloaded to take 1..N arguments using the preprocessor library or some other code generator. Then this code:
func(list_of<string>(), "foo", "bar", "baz");
might compile successfully and pass four arguments to func when I really meant to pass one argument:
func((list_of<string>(), "foo", "bar", "baz"));
Thorsten Ottosen wrote:
I think was the motivation. I had a user that called a constructor:
cons( list_of(3)(5), 4, 5 );
he wanted to pass 3 arguments, but only one was passed.
You got it backwards -- your example *does* pass three arguments. You have to add parentheses to only pass one: cons( (list_of(3)(5), 4, 5) );
Requiring paranthesis in certain contexts seems like a very subtle thing to do. I like easy syntax, but I also think surprising and subtle behavior can be a pain for users.
If you use the list_of comma syntax, surrounding parentheses are *always* required in every context. In most cases, forgetting the surrounding parentheses will result in a compile error. It doesn't seem so subtle to me; the consistency makes the rule easy to learn. -- Jon Willesen

Jon Willesen wrote:
Jon Willesen wrote:
The only other thing I can think of that concerns me at all is if I'm trying to call a function that has been overloaded to take 1..N arguments using the preprocessor library or some other code generator. Then this code:
func(list_of<string>(), "foo", "bar", "baz");
might compile successfully and pass four arguments to func when I really meant to pass one argument:
func((list_of<string>(), "foo", "bar", "baz"));
Thorsten Ottosen wrote:
I think was the motivation. I had a user that called a constructor:
cons( list_of(3)(5), 4, 5 );
he wanted to pass 3 arguments, but only one was passed.
You got it backwards -- your example *does* pass three arguments.
Not before I removed operator,() from the class returned by list_of(). That was my point. So pick your medicine: reintroduce it to satisfy your program and break his or leave it as it is to break yours. I think having that operator,() in the first release was a mistake. -Thorsten

Thorsten Ottosen wrote:
I think was the motivation. I had a user that called a constructor:
cons( list_of(3)(5), 4, 5 );
he wanted to pass 3 arguments, but only one was passed.
Jon Willesen wrote:
You got it backwards -- your example *does* pass three arguments.
Thorsten Ottosen wrote:
Not before I removed operator,() from the class returned by list_of().
That was my point.
Please see the attached program built with boost 1_32_0 which *does* have the comma operator. On both msvc 7.1 and g++ 3.4.2 it outputs: calling cons(list_of(3)(5), 4, 5) cons 3 calling cons( (list_of(3)(5), 4, 5) ) cons 1
So pick your medicine: reintroduce it to satisfy your program and break his or leave it as it is to break yours.
The above demonstrates his program won't break in the way you describe. The danger I was thinking of lies in passing more arguments than intended, not fewer.
I think having that operator,() in the first release was a mistake.
Because of the above results, I'm not convinced of that yet. But if you really want to keep the comma operator out, the list_of documentation needs to be updated. -- Jon

Jon Willesen wrote:
Thorsten Ottosen wrote:
Because of the above results, I'm not convinced of that yet. But if you really want to keep the comma operator out, the list_of documentation needs to be updated.
just curious, on which compiler(s) did you get those results? -Thorsten

Thorsten Ottosen wrote:
just curious, on which compiler(s) did you get those results?
As I already said, msvc 7.1 and g++ 3.4.2 (http://tinyurl.com/9354a).
Jon Willesen wrote:
Please see the attached program built with boost 1_32_0 which *does* have the comma operator. On both msvc 7.1 and g++ 3.4.2 it outputs:
-- Jon Willesen

Jon Willesen wrote:
Sorry, forgot the attachment...
Please see the attached program built with boost 1_32_0 which *does* have the comma operator. On both msvc 7.1 and g++ 3.4.2 it outputs:
calling cons(list_of(3)(5), 4, 5) cons 3 calling cons( (list_of(3)(5), 4, 5) ) cons 1
It does seem to work ok, that is, as you would expect. I still have a bad feeling about it. I lost my computer this summer when it was stolen, so my original private mails about the subject are lost. I'll make a new test and see how it works across the various compilers. -Thorsten
participants (2)
-
Jon Willesen
-
Thorsten Ottosen