Boost logo

Boost Users :

From: Edward Diener (eddielee_at_[hidden])
Date: 2006-07-29 11:08:42


Johan Råde wrote:
> Daryle Walker wrote:
>> On 7/28/06 10:04 AM, "Johan Råde" <rade_at_[hidden]> wrote:
>>
>>> Does Boost offer any facility for declaring basic_string literals in
>>> templates, i.e. something like
>>>
>>> basic_string<CharType> s = BOOST_STRING("foo");
>> No, it doesn't AFAIK. Would this provide anything useful if it did exist?
>> It wouldn't be a literal, since "basic_string" isn't a built-in type. That
>> means there is no compile-time savings; a string object is still created and
>> it happens at run-time. What advantage would it have over something like:
>>
>> std::string s( "foo" );
>>
>> If you really meant any "CharType" and not just "char", then a
>> "BOOST_STRING" macro would have to reference a locale (probably the default
>> global one) to perform a conversion.
>>
>
> Daryle,
>
> I ran into the problem when I wrote test cases for my facets for
> nonfinite numbers.
>
> I wanted to do something like:
>
> template<class CharType> void test()
> {
> basic_string<CharType> s1;
>
> ... some test code ...
>
> basic_string<CharType> s2 = "inf";
> BOOST_ASSERT(s1 == s2);
> }
>
> This will of course only compile if CharType is char.
>
> How would you fix this code, so that it compiles both for char and wchar_t?
>
> This is what I eventually came up with:
>
>
> #define S_(a) string_literal_helper(a, L##a)
>
>
> class string_literal_helper {
> public:
> string_literal_helper(const char* s, const wchar_t* ws) :
> s_(s), ws_(ws) {}
> operator std::string() { return s_; }
> operator std::wstring() { return ws_; }
> private:
> const char* s_;
> const wchar_t* ws_;
> };
>
>
> template<class CharType> void test()
> {
> basic_string<CharType> s1;
>
> ... some test code ...
>
> basic_string<CharType> s2 = S_("inf");
> BOOST_ASSERT(s1 == s2);
> }
>
>
> Now the code compiles both for CharType = char and CharType = wchar_t.
> The idea is not mine. I have seen it somewhere on the web.

I once brought up this problem on comp.std.c++. Someone suggested, along
the lines I was thinking, that C++ have a literal_cast<type>(literal
expression) to cast a literal from one type to another using type
notation. This would parallel the other C++ casts, such as static_cast
and dynamic_cast.

The notation L'char' ( and L"char-string" ), to cast from a narrow
character ( character string ) to a wide character ( wide character
string ) does not work nicely with templates as you have discovered,
whereas a literal_cast<type>(expression) would do so, ie
literal_cast<wchar_t>('char') ( or literal_cast<wstring>("char-string")
). In the literal_cast case, of course, one could use a character ( or
string ) template type as the type passed to literal_cast and an
equivalent narrow character or narrow string value, and always be
guaranteed of the correct result.

Of course literal_cast, if it existed, would work with any types which
are currently represented as a literal in C++, but needless to say its
main use would be to go from the C language L'' ( L"" ) notation to a
notation that worked correctly and effortlessly in template code.

However I have never written up such a suggestion to the C++ standard
comittee. I still find the idea correct, however.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net