(Why) Can't char* template parameters be const?

S

Steven T. Hatton

#include <iostream>

namespace ns{
const char name[] = "This is a Class Name";//won't compile
//char name[] = "This is a Class Name"; // compiles

template <typename T, char* Name_CA=name>
struct A {
A()
: _data(15)
, _name(Name_CA)
{}
T _data;
char* _name;
};

}

int main()
{
ns::A<int> a;

std::cout << a._name <<"\n";
return 0;
}

In function int main()
error: address of non-extern `ns::name' cannot be used as template
argument

I'm sure the explanation is buried somewhere in Clause 3 esoterica, but can
someone please explain in human readable form, why the version with const
char* won't compile?

--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
V

Victor Bazarov

Steven said:
#include <iostream>

namespace ns{
const char name[] = "This is a Class Name";//won't compile

Make it

extern const char name[] = "This is a Class Name";
//char name[] = "This is a Class Name"; // compiles

template <typename T, char* Name_CA=name>
struct A {
A()
: _data(15)
, _name(Name_CA)
{}
T _data;
char* _name;
};

}

int main()
{
ns::A<int> a;

std::cout << a._name <<"\n";
return 0;
}

In function int main()
error: address of non-extern `ns::name' cannot be used as template
argument

I'm sure the explanation is buried somewhere in Clause 3 esoterica, but can
someone please explain in human readable form, why the version with const
char* won't compile?

Because const char* by default has internal linkage. Non-type template
arguments are required to have external linkage.

Victor
 
J

John Harrison

Steven T. Hatton said:
#include <iostream>

namespace ns{
const char name[] = "This is a Class Name";//won't compile
//char name[] = "This is a Class Name"; // compiles

template <typename T, char* Name_CA=name>
struct A {
A()
: _data(15)
, _name(Name_CA)
{}
T _data;
char* _name;
};

}

int main()
{
ns::A<int> a;

std::cout << a._name <<"\n";
return 0;
}

In function int main()
error: address of non-extern `ns::name' cannot be used as template
argument

I'm sure the explanation is buried somewhere in Clause 3 esoterica, but
can
someone please explain in human readable form, why the version with const
char* won't compile?

Template parameters must have external linkage, const is implicitly internal
linkage in C++. Try

extern const char name[] = "This is a Class Name";

Not sure why template parameters must have external linkage though.

john
 
J

JKop

Template parameters must have external linkage, const is implicitly
internal linkage in C++. Try

extern const char name[] = "This is a Class Name";

Not sure why template parameters must have external linkage though.


Imagine you have two source files.


Both of them define the same template (by including its header file).


Both of them have a "const" global variable (which has internal linkage).

They both create a instance of this template (what's the correct lingo
there?) using their global variable.

The problem here is that, because "const" makes it internal linkage, the two
files could have different definitions of a variable of the same name, and
without violating the One Definition Rule. As a result:

Blah<monkey>();

in one file, will not be the same instance of the template as:

Blah<monkey>();

which resides in a different source file.


-JKop
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top