3

Lets consider this kind of template:

template<typename CharT>
std::basic_string<CharT> refEnvVaraiable(const std::basic_string<CharT> &varaibleName)
{
    std::basic_string<CharT> result;
    result.reserve(varaibleName.length() + 3);
    result = "${" + varaibleName + "}";
    return result;
}

Plan is that this suppose to handle strings with any character size. This of course will not compile if argument function argument is std::wstring since there is no operator to concat it with string literal of type const char[].

How to force string literal to match desired character type? Do I have to provide specializations for constants representing literals (this lots of boiler plate code)? Or is there a ready tool for it?

Live sample

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • 2
    This comes to mind: [How to express a string literal within a template parameterized by the type of the characters used to represent the literal?](https://stackoverflow.com/questions/9040247/how-to-express-a-string-literal-within-a-template-parameterized-by-the-type-of-t) – Geezer Sep 20 '18 at 11:38
  • @SkepticalEmpiricist this is some kind solution. Not nice, but it will work. I've come up also with [something like this](https://wandbox.org/permlink/hUSQoiKbGsS6fUcU), I don't like it, but it fits better to my needs (test code). – Marek R Sep 20 '18 at 11:49
  • Can you use C++17? I have a solution, it isn't the prettiest, but at least all the code would be in a single function. Basically it would use `if constexp`. – NathanOliver Sep 20 '18 at 12:39
  • Yes I can use C++17, your solution is just small improvement of answer linked in first comment. – Marek R Sep 20 '18 at 12:39

1 Answers1

1

One thing you can do is leverage if constexpr to code the different concatenations you want to support. When the code is compiled only the valid concatenation will get compiled and the rest will be discarded. That would give you something like

template<typename CharT>
std::basic_string<CharT> refEnvVaraiable(const std::basic_string<CharT> &varaibleName)
{
    std::basic_string<CharT> result;
    result.reserve(varaibleName.length() + 3);
    if constexpr (std::is_same_v<CharT, char>) result = "${" + varaibleName + "}";
    else if constexpr (std::is_same_v<CharT, wchar_t>) result = L"${" + varaibleName + L"}";
    else if constexpr (std::is_same_v<CharT, char16_t>) result = u"${" + varaibleName + u"}";
    else if constexpr (std::is_same_v<CharT, char32_t>) result = U"${" + varaibleName + U"}";
    else static_assert(false, "refEnvVaraiable called with unsupported character type");
    return result;
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402