Passing a const character * as a template argument





5.00/5 (1 vote)
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):
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:
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.
// 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:
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 string
s 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.