Home template pointer parameter pack
Reply: 2

template pointer parameter pack

GSi Published in 2018-02-12 18:23:31Z

Why a template function with a template parameter pack of pointers cannot be instantiated with offsets of the same pointer?

I mean: given this short code why must I comment out the last two lines?

template <int * ... pt> void f() {}

int n[] = {1, 2, 3};
int m = n[1];

int main()
    f<n>();  // this is accepted
    f<n, &m>();  // this is accepted too
    //f<n, n+1>(); // this is not.
    //f<n, &n[1]>(); // this isn't accepted neither

Doesn't n+1 represent the same address as &m ? Or there is a difference in the linkage? Or what else?

Olaf Dietsche
Olaf Dietsche Reply to 2018-02-12 19:14:58Z

See cppreference.com - Template non-type arguments

  • 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.


The only exceptions are that non-type template parameters of reference and pointer type cannot refer to/be the address of

  • a subobject (including non-static class member, base subobject, or array element);
  • a temporary object (including one created during reference initialization);

So the address of an array element is not allowed.

Barry Reply to 2018-02-12 21:42:57Z

In C++17, from [temp.arg.nontype]:

For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of):

  • a subobject,
  • [...]

Where a subobject is, from [intro.object]:

Objects can contain other objects, called subobjects. A subobject can be a member subobject ([class.mem]), a base class subobject ([class.derived]), or an array element.

Using &m as a non-type template argument is fine - it points to an object. That object happens to be initialized from n[1], but that doesn't matter.

On the other hand, n+1 and &n[1] both point to an element of the array n, which is to say they both point to a subobject of n, and hence this is not allowed. n+1 and &m are not related.

In C++11 and C++14, the wording was inclusive rather than exclusive, but the conclusion is the same:

A template-argument for a non-type, non-template template-parameter shall be one of:

  • [...]
  • a constant expression ([expr.const]) that designates the address of a complete object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as [...]
  • [...]

A pointer to m is allowed, a pointer to n[1] is not.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.311486 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO