Создать строки в зависимости от аргументов шаблона - PullRequest
14 голосов
/ 04 ноября 2010

У меня есть много классов / методов, подобных этому:

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).

Какой синтаксис должен использоваться для создания строк, которые не зависят от таких аргументов шаблона?

Ответы [ 3 ]

7 голосов
/ 04 ноября 2010

Вам действительно нужны разные литералы, или вы можете использовать конструктор итератора?

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();
1 голос
/ 04 ноября 2010

Вот решение с использованием 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. Если это не так, добавьте еще один параметр в макрос. НТН

1 голос
/ 04 ноября 2010

Если вы все равно собираетесь добавлять что-либо в строку, используйте поток строк:

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();
}

Мне также нравится ответ Стива Джессопа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...