I am very well aware that passing directly a const char*
as a template non-type parameter is erroneous, since two identical string literals defined in two different translation units may have different addresses (although most of the time the compilers use the same address). There is a trick one may use, see code below:
#include <iostream>
template<const char* msg>
void display()
{
std::cout << msg << std::endl;
}
// need to have external linkage
// so that there are no multiple definitions
extern const char str1[] = "Test 1"; // (1)
// Why constexpr is enough? Does it have external linkage?
constexpr char str2[] = "Test 2"; // (2)
// Why doesn't this work?
extern const char* str3 = "Test 3"; // (3) doesn't work
int main()
{
display<str1>(); // (1')
display<str2>(); // (2')
// display<str3>(); // (3') doesn't compile
}
Basically in (1) we declare and define an array with external linkage, which can then be used as a template parameter in (1'). I understand this very well. However, I don't understand:
-
Why the
constexpr
version (2) works? Doconstexpr
have external linkage? If not, then defining the same string literal in a different translation unit may lead with duplicate template instantiation. -
Why (3) doesn't work. It seems perfectly reasonable for me, but the compiler doesn't believe so:
error: 'str3' is not a valid template argument because 'str3' is a variable, not the address of a variable
Aucun commentaire:
Enregistrer un commentaire