4

I noticed that

template <size_t n, char[n]> class x
{
};

is happily accepted by my C++ compiler. However, when I naively attempt something like

x <4, "hey"> something;

I get a nice

Non type template argument does not refer to any declaration

So I wonder: how would I go with actually making a class out of that template?

3
  • My guess would be that your compiler is seeing the string literal of "hey" as a const char* not a char[] Commented Jun 7, 2016 at 23:18
  • What if you say x<5, "hey"> something;, I don't think the compiler is going to enforce the type safety here. Commented Jun 7, 2016 at 23:21
  • Related: stackoverflow.com/questions/5547852/… Commented Oct 28 at 16:38

2 Answers 2

4
#include <iostream>

template <size_t n, char s[n]>
class X {
public:
  X() {
    std::cout << s;
    std::cout << std::endl;
  }
};

char hey[] = "hey";

int main() {
  X<4, hey> x;
}

But X<4, "hey"> x; does not compile because, for a non-type template argument, certain restrictions apply:

For pointers to objects, the template arguments have to designate the address of an object with static storage duration and a linkage (either internal or external), or a constant expression that evaluates to the appropriate null pointer or std::nullptr_t value.

This raises another issue, I found the following on cppreference.com:

Array and function types may be written in a template declaration, but they are automatically replaced by pointer to object and pointer to function as appropriate.

So s is actually a pointer, therefore the following will compile:

X<5, hey> something;

Potential buffer-overflow problem.

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

3 Comments

I am not getting what the difference is between X<"hey"> and char hey[] = "hey"; X<hey>. Is there any way to use a more compact notation, something similar to the "hey" version?
In short, string literals do not have linkage, they don't even have names.
It's not supported in the current standard. stackoverflow.com/questions/2033110/…
1
template <size_t n, char[n]> class x
{
};

char foobar[]="hey";

x<4, foobar> y;

Compiles with gcc 5.3.1

1 Comment

I'd guess that argument needs to have linkage.

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.