templates - Fitting string literals for different string classes -


the problem

i implementing class want let user choose string type (std::string, std::wstring, std::u16string, ...) via template parameter. fail make string literals fit chosen string type: once decide literal prefix ("hello" vs. l"hello" vs. u"hello" vs. u"hello"), compilation errors incompatible string classes.

toy example

as example, consider following code (compile --std=c++11):

#include <string>  template<typename stringtype> void hello_string() {     stringtype result("hello"); }  int main() {     // works     hello_string<std::string>();     hello_string<std::basic_string<char>>();      // code below not compile     hello_string<std::wstring>();     hello_string<std::basic_string<unsigned char>>();     hello_string<std::u16string>(); } 

function hello_string() shows essence of want do: have string type template parameter, , assign string literals variables of type.

possible workaround

one way overcome problem implement several specializations of hello_string() function. problem lead several copies of each string literal - 1 each string literal prefix. think rather ugly, , there must better way.

another way chose "normal" string literals default values , have functions conversion different string types. while avoid code duplication, introduce unnecessary conversions of constant.

you can make macro. first define struct wraps char-choosing:

namespace details {      template<typename t>     struct templ_text;      template<>     struct templ_text <char>     {         typedef char char_type;         static const char_type * choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return narrow; }         static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return narrow; }     };      template<>     struct templ_text < wchar_t >     {         typedef wchar_t char_type;         static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return wide; }         static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return wide; }     };      template<>     struct templ_text < char16_t >     {         typedef char16_t char_type;         static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return u16; }         static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return u16; }     };      template<>     struct templ_text < char32_t >     {         typedef char32_t char_type;         static const char_type* choose(const char * narrow, const wchar_t * wide, const char16_t* u16, const char32_t* u32) { return u32; }         static char_type choose(char narrow, wchar_t wide, char16_t u16, char32_t u32) { return u32; }     }; } 

wrap nice macro:

#define templ_text(ch, txt) details::templ_text<ch>::choose(txt, l##txt, u##txt, u##txt) 

then function be:

template<typename stringtype> void hello_string() {     stringtype result(templ_text(typename stringtype::value_type, "hello")); } 

i think unused copies of string optimized away.


Comments

Popular posts from this blog

shopping cart - Page redirect not working PHP -

php - How to modify a menu to show sub-menus -

python - Installing PyDev in eclipse is failed -