Создание строк в зависимости от аргументов шаблона
У меня есть много классов/методов вроде этого:
template<typename CharT, typename TraitsT = std::char_traits<CharT> >
struct Foo
{
std::basic_string<CharT, TraitsT> getFoo(void) const
{
return "Foo"; // + this->member_var1 + this->member_var2...
}
};
Но в зависимости от CharT я должен использовать "," L "," u "или" U" (для char, wchar_t, u16char_t, u32char_t).
Какой синтаксис должен использоваться для создания строк, которые не зависят от таких аргументов шаблона?
Ответы
Ответ 1
Вам действительно нужны разные литералы, или вы можете использовать конструктор итератора?
const char *f = "Foo";
return std::basic_string<CharT, TraitsT>(f, f + 3);
Возможно, с чем-то более сильным, чем "3", если вы беспокоитесь о легкости изменения литерала в будущем.
В ответ на то, что это не очень хорошо, как насчет:
template <typename CharT, typename TraitsT, size_t N>
basic_string<CharT, TraitsT> proper_string(const char (&src)[N]) {
return basic_string<CharT, TraitsT>(src, src+N-1);
}
Затем у вас есть:
return proper_string<CharT, TraitsT>("Foo");
Если вам действительно нужен другой литерал, то единственное, о чем я думал до сих пор, это создать для него черты, что действительно ужасно:
template<typename T> struct FooString {
};
template<> struct FooString<char> {
static const char *value() { return "Foo"; }
};
template<> struct FooString<wchar_t> {
static const wchar_t *value() { return L"Foo"; }
};
... etc ...
return FooString<CharT>::value();
Ответ 2
Если вы все равно будете добавлять строки в строку, используйте stringstream:
std::basic_string<CharT, TraitsT> getFoo(void) const
{
std::basic_ostringstream<CharT, TraitsT> os;
os << "Foo";
// os << this->member_var1 << this->member_var2...
return os.str();
}
Мне нравится ответ Стива Джессопа.
Ответ 3
Вот решение, использующее MACRO
template < typename CharT >
struct char_t_literal_selector;
template <>
struct char_t_literal_selector< char > {
static const char *select( const char *s, const wchar_t *, const char16_t *, const char32_t * )
{
return s;
}
};
template <>
struct char_t_literal_selector< wchar_t > {
static const wchar_t *select( const char *, const wchar_t *s, const char16_t *, const char32_t * )
{
return s;
}
};
template <>
struct char_t_literal_selector< char16_t > {
static const char16_t *select( const char *, const wchar_t *, const char16_t *s, const char32_t * )
{
return s;
}
};
template <>
struct char_t_literal_selector< char32_t > {
static const char32_t *select( const char *, const wchar_t *, const char16_t *, const char32_t *s )
{
return s;
}
};
#define CHART_LITERAL(str) ( char_t_literal_selector< CharT >::select( str, L ## str, u ## str, U ## str ) )
template<typename CharT, typename TraitsT = std::char_traits<CharT> >
struct Foo
{
std::basic_string<CharT, TraitsT> getFoo(void) const
{
return CHART_LITERAL("Foo"); // + this->member_var1 + this->member_var2...
}
};
при условии, что имя параметра шаблона всегда CharT
. Если это не так, добавьте еще один параметр в макрос. НТН