Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Passing a const character * as a template argument

5.00/5 (1 vote)
30 Jun 2011CPOL 27.8K  
Consider a class template of the form (the method cout is just explanatory):template struct A { static void cout() { std::cout << str << std::endl; };};How can this template be instantiated?From the C++ standard can be understood that the address...
Consider a class template of the form (the method cout is just explanatory):

C++
template<const char* str> struct A {
    static void cout() {
        std::cout << str << std::endl;
    };
};


How can this template be instantiated?

From the C++ standard can be understood that the address of an object with external linkage may be passed, but nothing else. So passing string literals is not possible:

C++
struct B
void f() {
    typedef A<"Test 1"> A1; // VC++ 2008 C2762
    A1::cout();
}


Option 1
A C-style string is declared extern to avoid the limitation through the standard.
C++
// extern const char* s = "Test 2"; // VC++ 2008 error C2975 *)
extern const char s[] = "Test 2";   // OK

void f() {
    typedef A<s> A2;
    A2::cout();
}


Option 2
Also, static class members have external linkage. This resembles Ataul's approach:

C++
struct B
{
    static const char s[];
};
 
const char B::s[] = "Test 3";

void f() {
    typedef A<B::s> A3; 
    A3::cout();
}


As it can be seen, passing C-style strings as template parameters requires quite a lot of overhead and might have other negative consequences (option 1 practically gives global scope to s). I wonder if there is any real-life use for it.

*) My interpretation of this error is: For an array, information about its size is stored (it can be retrieved via the sizeof operator). When declaring s as const char*, the size information is lost and the compiler does not know how much text is inside the string.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)