3

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?

Matteo Monti
  • 8,362
  • 19
  • 68
  • 114

2 Answers2

3
#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.

xiaofeng.li
  • 8,237
  • 2
  • 23
  • 30
  • I am not getting what the difference is between `X<"hey">` and `char hey[] = "hey"; X`. Is there any way to use a more compact notation, something similar to the `"hey"` version? – Matteo Monti Jun 08 '16 at 08:53
  • In short, string literals do not have linkage, they don't even have names. – xiaofeng.li Jun 08 '16 at 22:40
  • It's not supported in the current standard. http://stackoverflow.com/questions/2033110/passing-a-string-literal-as-a-parameter-to-a-c-template-class – xiaofeng.li Jun 08 '16 at 22:42
0
template <size_t n, char[n]> class x
{
};

char foobar[]="hey";

x<4, foobar> y;

Compiles with gcc 5.3.1

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148