1

Is this a libstdc++ bug?

#include <string>
#include <sstream>

using namespace std;

int main() {
        basic_string<char16_t> str(u"0.0");
        basic_stringstream<char16_t> sstr(str);
        double x = 9;
        sstr >> x;
}

Output, under GCC 4.8 Linux x86_64:

$ ./main
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Aborted (core dumped)

Edit Can someone suggest a way to make this function work under GCC 4.9 without changing its signature:

template<typename T>
T fromString(std::basic_stringstream<char16_t>& stream)
{
    T v;
    stream >> v;
    return v;
}

Typical use is:

std::basic_string<char16_t> string(...);
std::basic_stringstream<char16_t> sstream(string);
double v = fromString<double>(sstream);
Tom
  • 7,269
  • 1
  • 42
  • 69
  • 4
    The streams are not required to support `char16_t` or `char32_t`, only `char` and `wchar_t`. – T.C. Feb 03 '15 at 08:17
  • 1
    Great. So, is there a way to make the above work? – Tom Feb 03 '15 at 08:51
  • a workaround tip: use utf-8 streams, then convert your string to utf-16 with tools like utfcpp: http://utfcpp.sourceforge.net/ – antonfrv Feb 03 '15 at 12:15
  • In fact it is just utterly broken, isn't it? `std::basic_string s; stream >> s;` produces the same exception. – Tom Feb 04 '15 at 06:54

1 Answers1

0

The standard doesn't require implementations to support streams of any type except char and wchar_t.

[iostreams.limits.pos]

In the classes of Clause 27, a template parameter with name charT represents a member of the set of types containing char, wchar_t, and any other implementation-defined character types that satisfy the requirements for a character on which any of the iostream components can be instantiated.

Additionally, it doesn't require facets used for extracting integers and floats from streams to work with char16_t either:

[category.numeric]

All specifications of member functions for num_put and num_get in the subclauses of 22.4.2 only apply to the specializations required in Tables 81 and 82 (22.3.1.1.1), namely num_get<char>, num_get<wchar_t>, num_get<C, InputIterator>, num_put<char>, num_put<wchar_t>, and num_put<C,OutputIterator>.

where C:

A template parameter with name C represents the set of types containing char, wchar_t, and any other implementation-defined character types that satisfy the requirements for a character on which any of the iostream components can be instantiated.

The standard only requires that char_traits (and so basic_string) and codecvt work correctly for char16_t and char32_t.

So to make your function work you would basically need to define specializations of all the missing pieces that the library doesn't provide.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521