The latest C++-standard (ISO-14882) requires that the standard C++-library is defined in namespace std::. Thus, to use classes from the standard c++ library, you can do one of three things:
Namespace portability-issues are not a problem with g++, because versions of g++ that do not have libstdc++ in std:: use -fno-honor-std (ignore std::, :: = std::) by default. This probably applies to some other compilers as well. The following sections list some possible solutions to support compilers that cannot ignore std::.
Gtk-- defines most of its classes in namespace Gtk::. Thus, it was possible to adapt Gtk-- to namespace std:: by using a C++-feature called namespace composition. This is what happens if you put a using-declaration into a namespace-definition: the imported symbol(s) gets imported into the currently active namespace(s). This is what it looks like in Gtk--:
namespace Gtk { using std::string; class Window { ... } }In this example, std::string gets imported into namespace Gtk::. The result is that you don't have to use std::string in this header, but still std::string does not get imported into user-space (the global namespace ::) unless the user does using namespace Gtk; (which is not recommended practice for Gtk--, so it is not a problem).
By defining an (empty) namespace std:: before using it, you can avoid getting errors on systems where no part of the library is in std:
namespace std { } using namespace std;
If some compilers complain about using std::string;, and if the hack for gtk-- mentioned above does not work, then it might be a good idea to define a macro NS_STD, which is defined to either "" or "std" based on an autoconf-test. Then you should be able to use NS_STD::string, which will evaluate to ::string ("string in the global namespace") on systems that do not put string in std::. (This is untested and might not even be necessary)
clanlib | usual |
pingus | usual |
mozilla | usual |
mnemonic | none |
libsigc++ | portable-impl |
usual | mostly fully qualified names and some using-declarations (but not in headers) |
none | no namespace std at all |
portable-impl | wrap all namespace-handling in macros to support compilers without namespace-support (no libstdc++ used in headers) |
I have seen ios::nocreate being used for input-streams, most probably because the authors thought it would be more correct to specify nocreate "explicitly". So you can simply leave it out for input-streams.
For output streams, "nocreate" is probably the default, unless you specify std::ios::trunc ? To be safe, you can open the file for reading, check if it has been opened, and then decide whether you want to create/replace or not.
With libstdc++-v3, you can use
basic_filebuf(int __fd, const char*__name, ios_base::openmode __mode)For a portable solution (if there is one), you need to implement a subclass of streambuf which opens a file given a descriptor, and then pass an instance of this to the stream-constructor (from the Josuttis-book).
The new headers can be seen in this source file.
I think it is a problem for libstdc++-v3 to add links or wrappers for the old headers, because the implementation has changed, and the header-name-changes indicate this. It might be preferable to use the new headers and tell users of old compilers that they should create links (which is what they will have to do sometime anyway).
The best solution I came up with so far is to include cctype instead of ctype.h wherever possible, and then use fully qualified names to refer to the libstdc++-versions: std::islower, std::isalnum etc. (you will need to as soon as any header includes <ctype.h>, because then there will be an ambiguity with the C-versions in the global namespace defined in <ctype.h>)
In previous versions of the standard, <fstream.h>, <ostream.h> and <istream.h> used to define cout, cin and so on. With libstdc++-v3, you need to include <iostream> to define these.
Please send any experience, additions, corrections or questions to fnatter@gmx.net or for discussion to the libstdc++-v3-mailing-list.