$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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.