This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Char_traits (part 2+)
- From: Benjamin Kosnik <bkoz at redhat dot com>
- To: jack_reeves at hotmail dot com
- Cc: libstdc++ at gcc dot gnu dot org
- Date: Fri, 16 Aug 2002 10:49:14 -0700
- Subject: Re: Char_traits (part 2+)
- Organization: Red Hat / San Francisco
- References: <F156GQvnbEG10Gai4om0000075f@hotmail.com>
> To summarize my interpretation of the Standard:
> 1. 21.1.1/1 is not a definition of template class char_traits<>. It is a
> statement of requirements – just like numerous similar tables in the
> Standard.
> 2. 21.1.1/2 requires a declaration of template class char_traits<>. It is
> not a definition either. It is also all we get.
> 3. 21.1.3.1 and 21.1.3.2 provide complete definitions of the explicit
> specializations template<> struct char_traits<char> and template<> struct
> char_traits<wchar_t> respectively. This suggests that the absence of a
> complete definition in (2) is deliberate.
> 4. It is not possible to provide a generic implementation of char_traits
> that meets the requirements of 21.1.1/1 without imposing additional
> requirements on the character type that are not mandated by the Standard.
Right. It's also not possible to do useful partial specializations for
char_traits due to only one template parameter.
The consensus seems to be that failing to provide a definition for
char_traits<_CharT> is strictly conforming, although not all that
friendly to users.
> Given these points, I consider any definition of template struct
> char_traits<> to be an implementation defined extension. Since an extension
> can be and do whatever it wants, we could just draw the line there and let
> it go at that.
See current sources....
> Nevertheless, I had problems with the original char_traits implementation
> because they were incorrect for most cases, and because of what I call the
> “like a duck” problem. This is: if it looks like a ‘character traits’ class,
> and calls itself a ‘character traits’ class, and is provided by the
> implementation, then reasonable users can be excused when they think it is a
> ‘character traits’ class – and for getting annoyed when they discover that
> it is not correct.
Right. Why should libstdc++ get in the way? Also, it's still not clear
to me that people would be able to specialize if the generic template is
defined before their specializations are declared.
> The changes address only part of this problem – now attempts to use
> char_traits<MyChar> will compile, but not link unless the user provides the
> definitions. First, the Standard is clear that adding explicit
> specializations of templates for built-in types to namespace std results in
> undefined behavior (17.4.3.1/1), so this doesn’t work for the expected
> common cases. Additionally, the solution provides no useful functionality
> for the user-defined types, so I do not see any point. In fact, it seems to
> promise functionality that is NOT provided, so unless the requirement that
> the users provide the function definitions is clearly spelled out somewhere,
> I think it is actually more confusing than just going with only what the
> Standard requires.
I guess I was thinking more of something like
typedef unsigned short unicode_type;
typedef unsigned char unsigned_type;
then doing
template<> struct std::char_traits<unicode_type>
{
// do the work
}
etc. Isn't this legal? Aren't these user-defined types, and thus allowed
to do the specialization of std::char_traits?
> (2) Let’s face it – the real issue is basic_string<>. Weirdo’s like me who
> mess with clause 27 are rare and presumably should know what they are doing.
Given the number of bug reports in this area I suspect you'd be
surprised at the number of freaks doing this stuff. I certainly was.
> A. Provide only what the Standard specifies without extensions. This has the
> advantage that code will be more likely to be portable. It has the major
> disadvantage that useful things like basic_string<unsigned char> will not
> work.
> B. Provide A plus implementation defined explicit specializations of the
> other built-in character types. This is my preference. I think it is in
> keeping with both the letter and the spirit of the Standard. It allows the
> useful things like declaring a basic_string<unsigned char>, but prevents
> accidental usage of more esoteric types.
Can "B" be provided as a generic skeletal stubs file that people fill in
for their own types (as above) instead of explicitly instantiated into
the libstdc++.so for all the builtin types? I'd like to do this, and
also provide a similar template (or stubs) for the locale bits that need
to be done in order to work with streams.
If so, I consider this mostly a documentation issue. Here's to patches
that address it!
I'm curious: I don't feel like you addressed the issue of _Traits
ambiguity in some of the locale facets (where _Traits is not a template
parameter, but _Chart and _Iter (which itself has a _Traits param) are.)
This came up in regards to your original email, where you used
MyCharType, instead of a std::char_traits<MyCharType> specialization.
What do you think about this?
Do you agree that analysis was correct? That was the big issue I had
with the second round of char_traits cleanup that I did, actually.
-benjamin