P0117: Generic to_string/to_wstring functions

99 wyświetleń
Przejdź do pierwszej nieodczytanej wiadomości

Robert Kawulak

nieprzeczytany,
1 paź 2015, 09:50:511.10.2015
do std-pr...@isocpp.org

Hi,

 

I've written the paper proposing addition of to_string/to_wstring function templates to the Standard Library. The functions are a concise replacement of the familiar ostringstream solution to get a string representation of an object and they generalise the existing to_string/to_wstring functions.

 

I'm not attending the Kona meeting – would somebody who does be so kind to present the paper to the Commitee in my name? If so, please let me know privately.

 

Also, discussion about the proposal is welcome.

 

Best regards,

Robert

Izzy Coding

nieprzeczytany,
1 paź 2015, 10:07:111.10.2015
do ISO C++ Standard - Future Proposals
I would agree generally with your proposal that something like this should exist in the standard.
Having said that I wonder if you would then also propose similar templated functions for:
  • to_int
  • to_uint
  • to_long
  • ... (you get the idea)

Or would you consider these not as important?


Also I believe these are so trivial that most people could implement them anyway. I would suggest maybe seeing if something like this would not be better as part of the GSL?

Robert Kawulak

nieprzeczytany,
1 paź 2015, 10:51:151.10.2015
do std-pr...@isocpp.org
Izzy Coding, 2015-10-01 16:07:10:
> Having said that I wonder if you would then also propose similar templated
> functions for:
> * to_int
> * to_uint
> * to_long
> * ... (you get the idea)
> Or would you consider these not as important?

There are already stol/stoul/stof/etc. functions in the Standard Library. A generic interface for those would be useful too, but currently I've focused only on the object->string side.

> Also I believe these are so trivial that most people could implement them
> anyway. I would suggest maybe seeing if something like this would not be
> better as part of the GSL?

Standard Library is supposed to contain stuff that is broadly useful, even if trivial, so it doesn't have to be implemented again and again by everyone on their own. GSL, on the other hand, seems to be narrowly focussed on tools related to Core Guidelines, and I don't remember seeing anything like to_string in the guidelines.

Izzy Coding

nieprzeczytany,
1 paź 2015, 12:55:271.10.2015
do ISO C++ Standard - Future Proposals
IMHO the standard library should contain things that are most likely to be used by most developers. However not everyone needs to_string in the way you are proposing.
Yes it is nice and generic, but what does it provide that I cant already do myself easily?

I suggested the GSL as maybe it could be a nice utility function and might be better as being a guideline for implementation.

If however you had proposed a to_string that would work on wstring and vice-versa I would say it is a brilliant idea as long as you were to take locale into account (however these sorts of things have been discussed and rejected many times).

But as I said that is just my opinion after having the same arguments previously on the exact same topic.
I am not against your proposal. I just don't currently see any major benefit to this.

Alisdair Meredith

nieprzeczytany,
1 paź 2015, 14:53:541.10.2015
do std-pr...@isocpp.org
I would be happy to champion this paper, as it effectively makes 'to_string' an ADL aspect that can be overloaded by users in their own namespace if they want something more efficient than the generic string stream implementation, much like we overload 'swap'.

I think text representation of arbitrary types is a niche, but a large and useful niche - for example we will often want this feature when testing our own libraries so the we can write meaningful debug strings.

I can probably run up some standardese in time for the meeting as well, if the proposal is well received.

Sent from my iPhone
--

---
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/.

Tony V E

nieprzeczytany,
1 paź 2015, 17:18:291.10.2015
do Standard Proposals
On Thu, Oct 1, 2015 at 2:53 PM, Alisdair Meredith <alis...@me.com> wrote:
I would be happy to champion this paper, as it effectively makes 'to_string' an ADL aspect that can be overloaded by users in their own namespace if they want something more efficient than the generic string stream implementation, much like we overload 'swap'.

If I need to do something similar to the "using std swap dance", I'll probably vote against it.
We really need a better STL extension mechanism.  I'd even be happy with the somewhat ugly std::to_string(x) calls std_to_string(x) with the latter being the one you overload (but never call directly - only the STL would call typically).

I find this analogous to Herb's Non-Virtual Interface guidance (http://www.gotw.ca/publications/mill18.htm) of making virtual functions (ie extension points) private, and making the user-facing interface non-virtual.

(Yes, I know, why don't I write a proposal then...)
 

I think text representation of arbitrary types is a niche, but a large and useful niche - for example we will often want this feature when testing our own libraries so the we can write meaningful debug strings.

Love or hate (likely hate here) Java, but it basically has it built in, and people in the java world find it very useful.  Particularly for debugging.
I think it is worthy of standardization.  (And if you hate java, replace with Python, etc)

I almost think there should be two versions - for debugging and for user display (which gets complicated - locales, etc).

Or if this is just (mostly) for debugging, maybe it should be named something more specific (to_debugstring, etc).  Or to_string<debug> or to_string(obj, context = debug) or ...

Matthew Fioravante

nieprzeczytany,
1 paź 2015, 19:10:551.10.2015
do ISO C++ Standard - Future Proposals

On Thursday, October 1, 2015 at 5:18:29 PM UTC-4, Tony V E wrote:
 
If I need to do something similar to the "using std swap dance", I'll probably vote against it.
We really need a better STL extension mechanism.  I'd even be happy with the somewhat ugly std::to_string(x) calls std_to_string(x) with the latter being the one you overload (but never call directly - only the STL would call typically).

I find this analogous to Herb's Non-Virtual Interface guidance (http://www.gotw.ca/publications/mill18.htm) of making virtual functions (ie extension points) private, and making the user-facing interface non-virtual.
 
I ranted about this in another thread and completely agree with you. Requiring "using std::XYZ" to use extension point XYZ() is insanity.
 
- It pollutes the your scope with the symbol where maybe you only wanted it for that one call.
- Its very easy to forget to do or not understand why you need to do it. (C++ expert only gotcha). I remember Andrei Alexandrescu's talk about scope guard he had to remind the audience to say using std::swap in his swap operator. If someone like him has to remind us how to correctly call swap() we have a problem. God forbid a newbie asks why, then you get to teach him how ADL works.
- You can never use the extension point in a one line expression. This means you can't use it in decltype (unless you do some hacks with detail:: namespaces) and therefore you can't easily use the extension points to define concepts, trailing return types, etc..
- Very verbose, extra boilerplate, and ugly. Most people (myself included) will still just call "v.begin();" instead of the technically more correct "using std::begin; begin(v);".
 
We are getting more and more of these (swap, begin, end, cbegin, cend, size, data, to_string, ...). A proper interface for these extension points should be decided on before we go too far down this rabbit hole.
 
Possible solutions:
- std::name() trys ADL name() first, then member name(), then either a default action (e.g. swap uses moves) or compiler error if there is no default.
- std::name() is the public interface, and you write an ADL std_name() (ignore bikeshedding for now) which std::name() calls. Tony's idea if I understood him correctly.
- Add overload of name() to the global namespace for built-in types. Probably a non-starter, but it can make ADL work without a using clause.
 
The uniform call syntax proposal is nice but it does not address the "using std::swap" problem.
 

Sam Kellett

nieprzeczytany,
2 paź 2015, 02:53:142.10.2015
do std-pr...@isocpp.org
agree completely with everything. this sucks so bad.

what about a new namespace that we are allowed to override (and create our own customization points)?

adl::swap()

or even:

std::adl::swap()

to avoid breaking changes.

it gets called fully qualified by the user and then compiler magic will do the adl dance from the namespace it was called in.

David Krauss

nieprzeczytany,
2 paź 2015, 03:37:552.10.2015
do std-pr...@isocpp.org
On 2015–10–02, at 2:53 PM, Sam Kellett <samke...@gmail.com> wrote:

agree completely with everything. this sucks so bad.

what about a new namespace that we are allowed to override (and create our own customization points)?

adl::swap()

Such a namespace name would be an oxymoron.

or even:

std::adl::swap()

How about simply “std::swap” and let it do the work of pulling in ADL?

to avoid breaking changes.

Question for all: Must qualified std::swap be supported as an accessor to the three-move algorithm, e.g. for ADL overloads that add side-effects but not optimization?

Perhaps it would be a good idea, going forward, to forbid ADL hooks from calling their std:: counterparts, so that std may encapsulate ADL.

Ville Voutilainen

nieprzeczytany,
2 paź 2015, 03:49:532.10.2015
do ISO C++ Standard - Future Proposals
On 2 October 2015 at 10:37, David Krauss <pot...@gmail.com> wrote:
> std::adl::swap()
>
> How about simply “std::swap” and let it do the work of pulling in ADL?
> to avoid breaking changes.

I have seen ruminations about a std::adl_swap that pulls in ADL.

David Krauss

nieprzeczytany,
2 paź 2015, 03:58:392.10.2015
do std-pr...@isocpp.org

On 2015–10–02, at 3:49 PM, Ville Voutilainen <ville.vo...@gmail.com> wrote:

I have seen ruminations about a std::adl_swap that pulls in ADL.

Me too, but I’ve not seen any speculation about simply fixing std::swap. I’m not sure if this is because implementing such a fix is trickier than adl_swap, or because it could lead to infinite recursion in corner cases. Hence asking whether the corner case is significant.

Sam Kellett

nieprzeczytany,
2 paź 2015, 04:07:092.10.2015
do std-pr...@isocpp.org
On 2 October 2015 at 08:37, David Krauss <pot...@gmail.com> wrote:

On 2015–10–02, at 2:53 PM, Sam Kellett <samke...@gmail.com> wrote:

agree completely with everything. this sucks so bad.

what about a new namespace that we are allowed to override (and create our own customization points)?

adl::swap()

Such a namespace name would be an oxymoron.

or even:

std::adl::swap()

How about simply “std::swap” and let it do the work of pulling in ADL? 

how would a user differentiate between a customization hook and something that isn't (like the rest of the std:: namespace)?

David Krauss

nieprzeczytany,
2 paź 2015, 04:13:042.10.2015
do std-pr...@isocpp.org

On 2015–10–02, at 4:07 PM, Sam Kellett <samke...@gmail.com> wrote:

how would a user differentiate between a customization hook and something that isn't (like the rest of the std:: namespace)? 

They wouldn’t. There would be no way to bypass a third-party library’s internal swap details, which sounds like a good thing.

It’s true, this would break libraries with bugs for which the workaround is to qualify std::swap. I’ll add to my question, is that breakage significant, either?

Sam Kellett

nieprzeczytany,
2 paź 2015, 05:14:492.10.2015
do std-pr...@isocpp.org
fair. is there any reason these hooks are adl-based instead of a template-specialization ala std::hash? that method of customization seems to have aged better (if not just w/r/t people's opinions of it) -- although i'm sure there's things that adl provides that wouldn't be possible otherwise?

Robert Kawulak

nieprzeczytany,
2 paź 2015, 10:33:332.10.2015
do std-pr...@isocpp.org
2015-10-01 20:53 GMT+02:00, Alisdair Meredith:
> I would be happy to champion this paper, as it effectively makes 'to_string'
> an ADL aspect that can be overloaded by users in their own namespace if they
> want something more efficient than the generic string stream implementation,
> much like we overload 'swap'.

I'm not sure to_string would make a good customisation point to
override the default implementation that is proposed, because this
implementation already has a customisation point: the string insertion
operator. So custom to_string(T) would have to be required to yield
results identical to insertion of T to a stream with default flags,
otherwise it would be very surprising that the results are
inconsistent depending on how you use to_string, like when ("value: "
+ to_string(t)) != to_string("value: ", t).

> I think text representation of arbitrary types is a niche, but a large and
> useful niche - for example we will often want this feature when testing our
> own libraries so the we can write meaningful debug strings.

It's also useful in other cases because of its (isolated) formatting
and concatenation capabilities, and useful in general for applications
not dealing with localisation/internationalisation. Some more examples
apart from those found in the paper:

- reliably changing text colour of a terminal using ANSI escape code:
cout << to_string("\x1b[", 30 + color, 'm');
If the escape sequence is not wrapped in to_string, it may be
corrupted by current formatting flags of stream (like hex or showpos).

- using C-style output interface for types supporting IO Streams interface:
printf("the value is '%s'", to_string(value).c_str());

> I can probably run up some standardese in time for the meeting as well, if
> the proposal is well received.

Thanks, I already have something on the way, I need to polish it though.

Matthew Fioravante

nieprzeczytany,
2 paź 2015, 12:58:222.10.2015
do ISO C++ Standard - Future Proposals


On Friday, October 2, 2015 at 3:37:55 AM UTC-4, David Krauss wrote:

How about simply “std::swap” and let it do the work of pulling in ADL?

to avoid breaking changes.

That's probably the easiest backwards compatibility story. The old using std::swap; swap() call has identical semantics to calling std::swap() with the new rules.

Also we can't rely on ADL alone at the callsite because of built-in types. That means a free function call will need to be namespace qualified. So better to qualify it with std:: than anything else.

Writing a convention wrapper like stl_begin is boilerplate because I'll still want a member named begin(). Requiring useless wrappers obscures and adds complexity to the the code and also adds more maintenance burden.

I should be able to write a member swap() or a non-member ADL swap() and expect calling std::swap() to just work. Same for begin(), size(), etc.. Make all of these things uniform and simple. I can also write a member to_string() and std::to_string calls it for me.
The order should be ADL first, member second, and then default or error.

Also swap() really should be a part of the "The rule of 0 or 6". That is, it should have =default,=delete support just like copy and move operations. Most of the time a perfectly optimal swap() just wants to swap() the members. If you aren't defining copy and move operations almost surely the =default swap implementation is what you want. std::swap can't do this because its impossible to write a template that calls swap() on all of the private data members of a type. That's a different proposal though...
 
Question for all: Must qualified std::swap be supported as an accessor to the three-move algorithm, e.g. for ADL overloads that add side-effects but not optimization?

Allow implicit swap() = default; like I just mentioned above, and you don't need this feature anymore.
 
Perhaps it would be a good idea, going forward, to forbid ADL hooks from calling their std:: counterparts, so that std may encapsulate ADL.

Sounds like a rule for the C++ guidelines project. A static analyzer can probably pick up a lot of violations of this rule. 

The big problem is if someone already calls std::swap from swap and upgrades, their code will change to an infinite loop.

Alternatively swap() could be an operator >=< like some other proposals have suggested. Then it can be overloaded in the global namespace for builtin types just like operator= allow ADL to work correctly.

ADL is insufficient by itself for "named operators" like swap() and begin(). ADL only works if the built-in types have overloads in the global namespace, which fine for operator overloading but not really a good practice for named functions. 
Odpowiedz wszystkim
Odpowiedz autorowi
Przekaż
Nowe wiadomości: 0