André Pönitz <poenitz@gmx.net> wrote in message news:<bjnla2$8ba$1@anderson.hrz.tu-chemnitz.de>...
[color=blue]
> Is there a way to make sure that a class will never be used for
> inheritance? [I don't think so but I thought I better ask][/color]
http://www.parashift.com/c++-faq-lit....html#faq-23.8 http://www.research.att.com/~bs/bs_f...#no-derivation
[color=blue][color=green]
> > However, before proceeding, try private inheritance combined with a
> > few well-placed using statements. That is safer.[/color]
>
> This would make both 'issues' go away, wouldn't it?[/color]
Mostly, yes. A private inheritance relationship is known only to the
derived class and its friends, so only they can use it
polymorphically. If they don't use it polymorphically, there is no
problem.
[color=blue]
> So to re-phrase Angus' original question: Why is std::string a typedef
> and not _privately_ derived from std::basic_string<char> with a lots of
> 'using' in it? [The benefit would still be there: to be able to
> forward-declare it][/color]
A few reasons. First and foremost, it wouldn't be a std::basic_string
instantation anymore, so it wouldn't work with templates that expect
std::basic_string. (I'm sure I could come up with other forward
declarations that might do worse.)
Second, it's a hack. I've used private inheritance and using
declarations to implement a new class in terms of an old one. But I'd
never recommend using them to fake forward declarations, certainly not
at the level of the Standard.
[color=blue]
> Or, alternatively:
>
> Why isn't there a 'slim' Standard <stringfwd> header?[/color]
Since we've got <iosfwd>, my guess is that they just forgot to put one
in. Sounds like something to be asked and/or debated on comp.std.c++.
:)
---
Incidentally, you can (depending on your intestinal fortitude)
forward-declare these things yourself. Herb Sutter tells us not to do
it in GOTW 34:
<quote url="http://www.gotw.ca/gotw/034.htm">
The standard says:
It is undefined for a C++ program to add declarations or definitions
to namespace std or namespaces within namespace std unless otherwise
specified.
</quote>
Of course, in the Real World, without which ISO C++ is meaningless,
I'd love to see an implementation which does anything worse than fail
to compile on a forward-declaration of std::string.
Herb continues:
<quote>
Among other things, this allows vendors to provide implementations of
the standard library that have more template parameters for library
templates than the standard requires (suitably defaulted, of course,
to remain compatible).
</quote>
But according to the official ISO C++ closed issues list, they can't:
<quote url="http://std.dkuug.dk/jtc1/sc22/wg21/docs/lwg-closed.html#94">
Library implementors are not permitted to add template parameters to
standard library classes.
</quote>
So, any compiler that doesn't supply the *exact* template interface is
non-conforming. If we know the interface, we ought to be able to
forward-declare it, like so:
namespace std {
template <typename> class char_traits;
template <typename> class allocator;
// cannot use default parameters in the forward declaration
template <typename, typename, typename> class basic_string;
// instead, use them here
typedef std::basic_string<char,
std::char_traits<char>,
std::allocator<char> > string;
}
But since this is heresy in comp.lang.c++, I suppose you're left to
including <string> whenever you need std::string, at least for now.
Better go get some coffee... This could take awhile. :)
- Shane