On the old comp.std.c++ Usenet list, I made a suggestion about adding the ability to move `basic_string`s into and out-of `basic_stringstream`s. I'm considering making this an actual C++ proposal, so I wanted to gauge the interest in doing this.
So is there any interest in this?
I'm wondering if a `.str() &&` overload is enough for our need.
--
Zhihao Yuan
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
I'm wondering if a `.str() &&` overload is enough for our need.
ostringstream o;
//Fill o
std::move(o).str();
o.move_str();
Yea, it looks more length, but it's using an existing semantics, so that we don't need to explain anything about the state of the stream after calling move_str(); people already know std::move.
--
Zhihao Yuan
Yea, it looks more length, but it's using an existing semantics, so that we don't need to explain anything about the state of the stream after calling move_str(); people already know std::move.
std::string s("Here is a string that contains characters.");
std::string::iterator stuff = std::move(s).begin();
I'm wondering if a `.str() &&` overload is enough for our need.
Permitting easy move semantics to and from basic_stream is a good reason to enforce it.
You're right, because when I do `f().str()`, then it works and seamlessly upgrades existing code, and move_str unnecessarily duplicates this functionality, forcing anyone who wants to use it to change all their code, for absolutely no benefit whatsoever.
Le samedi 11 mai 2013 05:14:58 UTC+2, Zhihao Yuan a écrit :I'm wondering if a `.str() &&` overload is enough for our need.
The standard gives implementations quite a bit of freedom. Overloading .str(string&&) is probably legal without changing the standard. Overloading .str()&& (and replacing the existing .str() with .str()const&) might be allowed as well.
You're right, because when I do `f().str()`, then it works and seamlessly upgrades existing code, and move_str unnecessarily duplicates this functionality, forcing anyone who wants to use it to change all their code, for absolutely no benefit whatsoever.
std::stringstream build;
build << /*stuff*/
std::string data = build.str();
On Saturday, May 11, 2013 12:07:31 PM UTC-7, Marc wrote:Le samedi 11 mai 2013 05:14:58 UTC+2, Zhihao Yuan a écrit :I'm wondering if a `.str() &&` overload is enough for our need.
The standard gives implementations quite a bit of freedom. Overloading .str(string&&) is probably legal without changing the standard. Overloading .str()&& (and replacing the existing .str() with .str()const&) might be allowed as well.
I'm not sure what you mean by "without changing the standard". Could an implementation add those overloads as an extension?
Yes. But you can't rely on it "without changing the standard" to require that implementations provide them.
Also, adding `.str() &&` would change apparent behavior as well, as it would leave the stringstream in the moved-from state.
Le dimanche 12 mai 2013 05:26:34 UTC+2, Nicol Bolas a écrit :On Saturday, May 11, 2013 12:07:31 PM UTC-7, Marc wrote:Le samedi 11 mai 2013 05:14:58 UTC+2, Zhihao Yuan a écrit :I'm wondering if a `.str() &&` overload is enough for our need.
The standard gives implementations quite a bit of freedom. Overloading .str(string&&) is probably legal without changing the standard. Overloading .str()&& (and replacing the existing .str() with .str()const&) might be allowed as well.
I'm not sure what you mean by "without changing the standard". Could an implementation add those overloads as an extension?
Not "as an extension", as a valid implementation of the standard.
Also, adding `.str() &&` would change apparent behavior as well, as it would leave the stringstream in the moved-from state.
Yes, that's why I was asking if the generic text about rvalues and moving in the standard library covers this case.
On the old comp.std.c++ Usenet list, I made a suggestion about adding the ability to move `basic_string`s into and out-of `basic_stringstream`s. I'm considering making this an actual C++ proposal, so I wanted to gauge the interest in doing this.
Le dimanche 12 mai 2013 11:45:02 UTC+2, Nicol Bolas a écrit :On Sunday, May 12, 2013 1:25:29 AM UTC-7, Marc wrote:Le dimanche 12 mai 2013 05:26:34 UTC+2, Nicol Bolas a écrit :On Saturday, May 11, 2013 12:07:31 PM UTC-7, Marc wrote:Le samedi 11 mai 2013 05:14:58 UTC+2, Zhihao Yuan a écrit :I'm wondering if a `.str() &&` overload is enough for our need.
The standard gives implementations quite a bit of freedom. Overloading .str(string&&) is probably legal without changing the standard. Overloading .str()&& (and replacing the existing .str() with .str()const&) might be allowed as well.
I'm not sure what you mean by "without changing the standard". Could an implementation add those overloads as an extension?
Not "as an extension", as a valid implementation of the standard.
No, you can't. `str` is not allowed to affect the state of the stream in any way. There's no viable way to move a string out of `str` that doesn't affect the stream. At least, not without making the "move" into a "copy", which defeats the entire point of the optimization.Also, adding `.str() &&` would change apparent behavior as well, as it would leave the stringstream in the moved-from state.
Yes, that's why I was asking if the generic text about rvalues and moving in the standard library covers this case.
No. And there never will be.
To allow such text would create chaos. It would mean that you have no idea what the state of an object is in when you call it on something that happens to bind to the `&&` version rather than the `&` version of the function.
Movement is not something that can ever be implicit or accidental. It must be explicitly stated by every function that attempts to move.
Because movement is explicit (either you passed a temporary, or you passed move(obj)), binding to && is not an accident, it is done on purpose, and there is thus no way it creates chaos.
Note for instance 17.6.4.9:
"... If a program casts an lvalue to an
xvalue while passing that lvalue to a library function (e.g. by calling the function with the argument
move(x)), the program is effectively asking that function to treat that lvalue as a temporary. The
implementation is free to optimize away aliasing checks which might be needed if the argument was
an lvalue."
If a function argument binds to an rvalue reference parameter, the implementation may assume that
this parameter is a unique reference to this argument.
On Friday, May 10, 2013 6:14:32 PM UTC+2, Nicol Bolas wrote:On the old comp.std.c++ Usenet list, I made a suggestion about adding the ability to move `basic_string`s into and out-of `basic_stringstream`s. I'm considering making this an actual C++ proposal, so I wanted to gauge the interest in doing this.Interesting!What about variants that take the buffer by reference and input/output directly into the buffer, with buffer (views) being generic?
Isn't an implementation allowed to move a string into a stringstream already?
I, for one, would welcome normative text saying that if you pass an rvalue reference to any library function, the value upon return from that function is unspecified. I don't expect to have time to write the paper, but it would be great to get it for C++17.
Jeffrey
On Sun, May 12, 2013 at 10:00 AM, Nicol Bolas <jmck...@gmail.com> wrote:
> `std::basic_stringstream::str` does not take `this` as an "rvalue reference
> parameter".
But it's our job to make it work, right?
Before
std::string str() const
After
std::string str() &&
std::string str() const&
I can't see the problem...
I see. I had no ABI compatibility concern in mind and this problem only occurs when an explicit call to std::move was used. Anyway, you are right.
And the next question is, does it worth to break a (almost) non-existing practice? Does it worth to add one member function semantically as same as std::move to workaround the problem? In what way the APIs in the future can benefit from the choices people currently make?
--
Zhihao Yuan
--
I see. I had no ABI compatibility concern in mind and this problem only occurs when an explicit call to std::move was used. Anyway, you are right.
And the next question is, does it worth to break a (almost) non-existing practice? Does it worth to add one member function semantically as same as std::move to workaround the problem? In what way the APIs in the future can benefit from the choices people currently make?
On Sunday, May 12, 2013 6:21:23 AM UTC-7, Marc wrote:Because movement is explicit (either you passed a temporary, or you passed move(obj)), binding to && is not an accident, it is done on purpose, and there is thus no way it creates chaos.It creates chaos because the standard is supposed to specify the state of objects after each function. Explicitly. If a function does not say that the state of the object is affected by the function, then the function may not affect the state of that object.
None of that is the actual, normative text.
`std::basic_stringstream::str` does not take `this` as an "rvalue reference parameter". Therefore, any implementation that did split the function between `&` and `&&` versions and did indeed move the string out of the object would be in violation of the standard.
`std::basic_stringstream::str` does not take `this` as an "rvalue reference parameter". Therefore, any implementation that did split the function between `&` and `&&` versions and did indeed move the string out of the object would be in violation of the standard.
That's where we disagree. I think an implementation is already allowed to do it. And if it isn't, it should. That would only help.
On 12 May 2013 21:39, Ville Voutilainen <ville.vo...@gmail.com> wrote:On 12 May 2013 21:22, Marc <marc....@gmail.com> wrote:`std::basic_stringstream::str` does not take `this` as an "rvalue reference parameter". Therefore, any implementation that did split the function between `&` and `&&` versions and did indeed move the string out of the object would be in violation of the standard.
That's where we disagree. I think an implementation is already allowed to do it. And if it isn't, it should. That would only help.
17.6.5.5 Member functions [member.functions]/2:
An implementation may declare additional non-virtual member function signatures within a class:
..
- by adding a member function signature for a member function name.
3 A call to a member function signature described in the C ++ standard library behaves as if the implementation
declares no additional member function signatures. Footnote 187
187) A valid C ++ program always calls the expected library member function, or one with equivalent behavior. An implemen-
tation may also define additional member functions that would otherwise not be called by a valid C++ program.
In other words, a library implementation is allowed to add the overloads we're talking about.Now, let's create a proposal that actually adds those overloads explicitly, rather than rely on implementations
to do it, please.
Ah, just one more thing, says Lt. Columbo - if an rvalue reference overload actually moves, it's not equivalent
in behavior, and the behavior difference is easy to detect. I think we actually _need_ to add those overloads
to the standard and specify the semantics.