14

I have many classes/methods like this:

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...
   }
};

But depending on CharT, I have to use "", L"", u"" or "U" (for char, wchar_t, u16char_t, u32char_t).

What syntax must be used to create strings that are independed from such template arguments?

0

3 Answers 3

7

Do you really need the different literals, or can you use the iterator constructor?

const char *f = "Foo";
return std::basic_string<CharT, TraitsT>(f, f + 3);

Maybe with something a bit more robust than "3" in there, if you're worried about ease of changing the literal in future.

In response to the point that this isn't very nice, what about:

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

Then you have:

return proper_string<CharT, TraitsT>("Foo");

If you really need the different literal, then the only thing I've thought of so far is to create traits for it, which is really horrible:

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();
Sign up to request clarification or add additional context in comments.

10 Comments

Use a character array instead of a pointer to const char, and use sizeof f instead.
const char f[] = "Foo"; return std::basic_string<CharT, TraitsT>(f, f + sizeof f)
Creating from two iterators is a workaround, but not a nice solution for many such situations.
@dreamlax: that would certainly work, but I'm not sure whether to trust the compiler not to make an unnecessary copy if I use an array.
@dreamlax: and both "4" and sizeof f are wrong anyway, since we don't want the NUL terminator in the string. Which proves some point or other, probably that you really don't want to have to specify the length every time you do this.
|
1

If you're going to be appending things to the string anyhow, use a 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();
}

I like Steve Jessop's answer, too.

Comments

1

Here is a solution using a 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...
   }
};

assuming the template parameter name is always CharT. If it is not, add another parameter to the macro. HTH

1 Comment

This is better than my solution for getting the literal (I think), but I'm not sure if the literal is actually needed, or just the basic_string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.