4

While the C++ standards doesn't allow to use string literals as template-arguments, it is allowed things like this:

ISO/IEC 14882:2011

14.3.2 Template non-type arguments [temp.arg.nontype]

2 [ 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 ]

So why the following code gives me an error in all compilers (gcc 4.7.2, MSVC-11.0, Comeau)?

template <const char* str>
void foo() {}

int main()
{
   const char str[] = "str";
   foo<str>();
}
1
  • +1 it used to work with something like MSCV 6 or 7. But last time I tried it no longer compiled :-( Glad you ask the question. Commented Jan 9, 2013 at 17:22

2 Answers 2

5

Rewind a few lines.

14.3.2/1: a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage.

Sign up to request clarification or add additional context in comments.

Comments

4

Note that the following modification works:

template <const char* str>
void foo() {}

char str[] = "str";

int main() {
    foo<str>();
}

See http://www.comeaucomputing.com/techtalk/templates/#stringliteral for a short explanation.

12 Comments

You're right, removing const helps. However, I think it just demonstrates a compiler bug in code handling constants, because const char p[]="" still defines an external object.
@Cornstalks: Oh yes, const is important here: compare ideone.com/rY7ZWI and ideone.com/u4LbEC (although you are right not using a local variable is essential, I was just trying variations of it and came across the const thing...)
Hmm, I think the term in the standard is "external linkage" (not "external object"). Objects having namespace scope declared const have internal linkage. I'm not a good language lawyer, but I don't think this is a compiler bug.
@mkluwe: According to n.m.'s quote it needs to be an object with "static storage duration and external or internal linkage" (so unless const makes it have non-static storage duration, it should theoretically work, regardless of whether it's external or internal linkage). I'm too lazy to figure out exactly how const affects this all, though. But I'd say it's a compiler bug, seeing as the standard's example code fails: http://ideone.com/YQNCfB
@Cornstalks C++03 requires external linkage, and a const at namespace scope has internal linkage. It's not a compiler bug (but one could argue that it is a bug in the standard).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.