Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Perhaps for Android, but I'm hesitant about using Clang for Win64 due to some recent bugs (such as tellg not working correctly).


That's probably a bug in libc++, not Clang. They're under the same roof, but different people work on them.

Also, I would mock you for using <iostream> at all but you've probably got legacy code just the same as I do.


I'm curious, what's wrong with iostream?


It's a pain to format text. Things like: printing an int in hex, printing a zero-padded int of a specific length, printing a float to two decimal places. And having those formatting changes be stored silently as global state leads to unexpected behavior.


FWIW, most of these options revert back to default as soon as you format something; but I agree that I would have preferred iomanip to generally be a wrapper around values rather than a silent modifier of the stream.


Which is worse than none of them reverting back to default..


(...and if it makes you feel any worse, I got curious when I saw your response which ones didn't reset, and it turns out I had it backwards: most of them don't reset, except the one that does :/.)


How do you internationalize strings built up from multiple string fragments?


Link for those who need more context: http://yosefk.com/c++fqa/web-vs-c++.html#misfeature-4


The same way you'd do it in printf? Stringize data and insert it in the middle of static text? (Pardon my inelegant code, I've been away from C++ and doing Erlang for quite a while now.)

  void printStuff(ostream Os, 
   string WarningPart, string SizePart, string EndPart, int Size) {
    //The English version might look like:
    //"Warning: Size too big (200). Get smaller."
    Os << WarningPart << SizePart << Size << EndPart << endl;
  };
I expect that if I thought about the problem for a few minutes (and was unable to find any C++ i18n libraries) I would come up with something much nicer and easier to use than this thing I spent ten seconds working on. :)


POSIX printf allows a translator to write a conversion spec like "%1$d" that says which arg to print. This lets you do stuff like put currency before or after the amount depending on what's idiomatic for the locale, without recompiling (if you lookup your format strings at runtime).


Sure, but that's l10n, which is a different -but related- thing. :)

printf format strings are well thought-out. I was demonstrating that the same ideas can easily be used with io*stream.


For the downvoters: Here's a lib that accomplishes this task that's had a fair bit more than 10 seconds of thought put into it: [0]. Examples [1][2].

:)

[0] http://www.boost.org/doc/libs/1_60_0/libs/locale/doc/html/in...

[1] http://www.boost.org/doc/libs/1_60_0/libs/locale/doc/html/he...

[2] http://www.boost.org/doc/libs/1_60_0/libs/locale/doc/html/me...


That solution is good, but it assumes you can break the message up into those parts for every language and use the same iostream sequence for every language.

With printf, we have gettext. I don't really see how there's any analogy for gettext in iosream-world.


> With printf, we have gettext. I don't really see how there's any analogy for gettext in iosream-world.

Funny thing. Boost more-or-less uses gettext, too! https://news.ycombinator.com/item?id=10774941


Am I being downvoted for asking an honest question?


It's better to engage with the folks who have provided responses to your questions than to complain about downvotes.


I dunno, I think bit shifting a string to write to a file is pretty unreadable, not to mention C already has rock-solid string formatting options. It's an miasma of operator abuse built into "hello world".


> ...I think bit shifting a string to write to a file is pretty unreadable...

If you have a fundamental misunderstanding of the meaning of an operator, it's pretty easy to fail to correctly read a section of code.

Maybe you're someone who hates operator overloading. If so, that's a pity. It's a useful power tool. [0]

[0] Yes, all power tools can be abused. That conversation is tired and not worth revisiting.


> C already has rock-solid string formatting options

Don't troll.


Do you have an actual response? How is iostream any better than *printf? At least you can read the format of the former without needing to google un-googleable operators.


In addition to the already-mentioned type safety and user-defined operator<< /etc overloading, it's very liberating to read into a std::string and not have to do a bunch of memory management and worry about null-termination or buffer overflows.


> How is iostream any better than [<star>]printf?

What consistent mechanism do you use to printf an instance of an arbitrary user-defined type?

With ostream, you implement

  ostream& operator<<(ostream&, const Class&)
and you're done.

with printf, you have to have a convention and remember to stick to it. (Do I call .toString(), .stringize(), .getString()... ??)

For one-off things, printf is great. You take it from me when you pry it from my goddamn cold, dead, hands. However, for real work io*stream are rather nice.


With printf, you do have to look at the docs to see what the string conversion function is. With iostream, you still have to look at the docs to see if the ostream operator is implemented for the class, it's certainly not universal.


> look at the docs to see if the ostream operator is implemented for the class

Or give it a go and see if the ide/compiler complains.


It has been so long that that bit of information had dropped out of my brain. I went to verify, and -obviously- there is no auto-conversion for instances of a non-trivial class.

Thanks for reminding me of this. Kudos!


I never said io*stream support was universal, [0] I said that it provided a _consistent_ mechanism. :)

[0] I mean, it's obvious that anything that you don't get for free out of the box is bound to _not_ be universal. Edit: Actually, the thing you get out of the box when you present an instance of a non-trivial user-defined class to both printf and ostream is equally useless... unless you're debugging and are interested in the address of the instance of an object.


Right, I'm just questioning whether this consistency buys you anything. Either way you're checking the docs to see how to print an object.


> ...I'm just questioning whether this consistency buys you anything.

It buys you the same thing that API consistency always buys you: reduced cognitive overhead when dealing with a given API. :)

Edit: As GFK_of_xmaspast mentions [0] instances of non-trivial classes are not compatible with the default implementations of "operator <<" in ostream. So, you can try "ostream << instanceOfNonTrivial". If it passes the compiler, then you know that operator << is defined for that class.

So, no need to check the docs... just ask the compiler. :)

[0] https://news.ycombinator.com/item?id=10775022


I find that how I print my data changes depending on why I'm printing, making a convention necessary anyways. Is the ostream overload the user-visible format, the test-failure format, or the serialization format?


noob question - what is the use case for a program that operates on arbitrary user defined types? Dynamic typing sounds lazy and slow in my head, might as well use python at this point


> ...what is the use case for a program that operates on arbitrary user defined types?

That's not what's going on. Neither C nor C++ really permits that.

We're just talking about the relative merits of using printf and friends vs. using iostream to format data for the console or disk.

In either case, you have to write the code for your class that massages the class's internals correctly, but the question is, do you write to the ostream extraction and istream insertion API, or do you write to the substantially less well defined printf-and-friends API?


> How is iostream any better than *printf?

Type checking.


printf has type checking in every major compiler. You just need to annotate all of your printf-y functions with attributes to tell the compiler "this function does printf, the format string is the nth argument, and the format arguments start at the mth argument".

It doesn't work with non-constexpr format strings, but there aren't many justifications for those.


You already have to do odd casting to get around compiler warnings when passing invalid types to a format—I don't buy this anymore.


> I don't buy this anymore.

You should: https://news.ycombinator.com/item?id=10775022


> How is iostream any better than *printf? printing user-defined types?


NDK is only for Android (as in a C++ toolchain for Android, the toolchain runs on Windows, Linux and Mac but the resulting executables are meant for Android) ... what do you mean with Win64 in this context ?


He probably meant the x64 compiler on Windows.

From the link: "Also note that Clang packaged in the Windows 64 NDK is actually 32-bit."




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: