C-Style Strings as template arguments?


Question

Can C-Style strings be used as template arguments?

I tried:

template <char *str>
struct X
{
    const char *GetString() const
    {
         return str;
    }
};

int main()
{
    X<"String"> x;
    cout<<x.GetString();
}

And although I get no complaints about the class definition, the instantiation yields 'X' : invalid expression as a template argument for 'str' (VC).

1
49
2/11/2014 7:25:22 AM

Accepted Answer

A string literal cannot be used as a template argument.

Update: Nowadays, a few years after this question was asked and answered, it is possible to use string literals as template arguments. With C++11, we can use characters packs as template arguments (template<char ...c>) and it is possible to pass a literal string to such a template.

This would work, however:

template <char const *str>
struct X
{
    const char *GetString() const
    {
         return str;
    }
};

char global_string[] = "String";

int main()
{
    X<global_string> x;
    cout<<x.GetString();
}
47
3/26/2019 7:27:46 PM

Sorry to post on such an old question, but here's what I feel is the cleanest approach to actually pass a literal as the argument without using storage.

Encode the string as a type:

template <char... chars>
using tstring = std::integer_sequence<char, chars...>;

Create a user defined literal operator:

template <typename T, T... chars>
constexpr tstring<chars...> operator""_tstr() { return { }; }

And use partial specialization to recover the character data as needed:

template <typename>
struct X;

template <char... elements>
struct X<tstring<elements...>> {
    const char* GetString() const
    {
        static constexpr char str[sizeof...(elements) + 1] = { elements..., '\0' };
        return str;
    }
};

This allows you to write:

X<decltype("my_string"_tstr)>

The user defined literal uses non-standard (n3599) functionality not in C++14 but that is supported by recent GCC and Clang builds, and hopefully will be reconsidered for C++1z.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon