Martin's Tex-Blog

Posts on programming and generally technical topics

String literal as non type template parameter

leave a comment »

Unfortunately it is not possible to have template with string literal as a non type parameter. Until C++11 reason was that string literals had internal linkage, while non type template parameters allowed only external linkage pointers. It makes sense because templ_class should have the same typeid in all translation units. It kind of could work with string pooling enabled – which is availabe for both gcc and msvc. After C++11 the reason is more of that string literals does not match any of the allowed entities as template parameter.

You can use character array initialized with string literal as non type parameter. It compiles both with g++ and msvc:

#include <typeinfo>

template<const char* STR>
class MyStr {};

extern const char my_string[]; const char my_string[] = "alfabet";
extern const char my_string2[]; const char my_string2[] = "alfabet";

// or use constexpr
//constexpr const char my_string[] = "alfabet";
//constexpr const char my_string2[] = "alfabet";

extern const char* my_string_pc;
const char* my_string_pc = "alfabet";

int main(){
    // This fails with:
    //  main.cpp:30:31: error: 'my_string_pc' is not a valid template argument because 'my_string_pc' is a variable, not the address of a variable
    //    typedef MyStr<my_string_pc> str_type3;
    typedef MyStr<my_string_pc> str_type3;     
    // Below compiles, but gives different types
    typedef MyStr<my_string> str_type1;   
    typedef MyStr<my_string2> str_type2; 
    // This fails
    static_assert(std::is_same<str_type1, str_type2>::value, "");
    return 0;

After writing it I have found in standard ([temp.arg.nontype]) the actual reasoning for all above:

[ Note: A string literal (2.14.5) does not satisfy the requirements of any of these categories and thus is not
an acceptable template-argument. [ Example:

template<class T, const char* p> class X {
/ ... /
X<int, "Studebaker"> x1; // error: string literal as template-argument
const char p[] = "Vivisectionist";
X<int,p> x2; // OK

—end example ] —end note ]



Written by Marcin

December 30, 2014 at 12:56 am

Posted in C++, Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: