This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
RE: a string problem
- To: "'libstdc++ mailing list'" <libstdc++ at sourceware dot cygnus dot com>
- Subject: RE: a string problem
- From: scleary at jerviswebb dot com
- Date: Wed, 13 Oct 1999 08:34:47 -0400
- Reply-To: <scleary at jerviswebb dot com>
> > #include <string>
> >
> > void foo() { std::string s(10,0); }
>
> whoops. This is not a compiler or library implementation bug--the
> arugments get deduced as iterators, as you pointed out earlier. You'll
> have to cast to
>
> string s(10, char(0)) to call the constructor that you're intending.
>
I beg to differ. It is an implementation bug, according to ANSI 21.3.1 para
15, which states for constructor "template <class InputIterator>
basic_string(InputIterator begin, InputIterator end, const Allocator & a =
Allocator());": "If InputIterator is an integral type, [this constructor
call is] equivalent to 'basic_string(static_cast<size_type>(begin),
static_cast<value_type>(end))'" Also see ANSI 23.1.1 para 9-11.
ANSI 23.1.1 para 11 states "One way that sequence implementors can satisfy
this requirement is to specialize the member template for every integral
type. Less cumbersome implementation techniques also exist."
If I may suggest a "less cumbersome implementation technique":
For each function "func" with return type "ret_type" which may have either
input iterators or size/value combinations, do the following:
struct ct_true { }; struct ct_false { };
template<bool Truth> struct ct_if;
template <> struct ct_if<true> { typedef ct_true type; };
template <> struct ct_if<false> { typedef ct_false type; };
public:
template<class InputIterator>
ret_type func(InputIterator a, InputIterator b)
{ return do_func(a, b,
ct_if<std::numeric_traits<InputIterator>::is_integer>::type()); }
ret_type func(size_type a, value_type b)
{ return do_do_func_n(a, b); } // skip straight to implementation (see
below)
private:
template <class InputIterator>
ret_type do_func(InputIterator a, InputIterator b, ct_true)
{ return do_do_func_n(static_cast<size_type>(a),
static_cast<value_type>(b)); }
template <class InputIterator>
ret_type do_func(InputIterator a, InputIterator b, ct_false)
{ return do_do_func(a, b); }
// the actual action for size/value combination
ret_type do_do_func_n(size_type a, value_type b)
{ ... }
// the actual action for range of iterators
template <class InputIterator>
ret_type do_do_func(InputIterator a, InputIterator b)
{ ... }
This technique works on Borland's C++ Builder (which is the only platform I
currently have). The ct_if/ct_true/ct_false hacks are because of BCB
limitations. For GNU, these hacks may not be necessary (all we're really
doing is specializing the function do_func with a boolean parameter, but BCB
doesn't allow member template specializations).
Hope this helps!
-Steve