Title
Address of subobject as non-type template argument
Status
c++14
Section
13.4.3 [temp.arg.nontype]
Submitter
Michael Wong

Created on 2012-02-06.00:00:00 last changed 122 months ago

Messages

Date: 2013-09-15.00:00:00

[Moved to DR at the September, 2013 meeting.]

Date: 2013-06-15.00:00:00

Proposed resolution (June, 2013):

Change 13.4.3 [temp.arg.nontype] paragraph 1 as follows:

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

  • ...

  • a constant expression (7.7 [expr.const]) that designates the address of an 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 & id-expression, where the id-expression is the name of an object or function, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; or

  • ...

Date: 2013-04-15.00:00:00

Notes from the April, 2013 meeting:

CWG did not favor extending the range of non-type template arguments to include subobjects, feeling that they should continue to be restricted to the address of a complete object.

Date: 2012-02-06.00:00:00

According to 13.4.3 [temp.arg.nontype] paragraph 1, the argument for a non-type template parameter of pointer or reference type must be

a constant expression (7.7 [expr.const]) that designates the address of an 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 & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference

In C++03, the requirement for an id-expression eliminated the use of “addresses of array elements and names or addresses of non-static class members,” as noted in paragraph 3 of that section. With the advent of generalized constant expressions, however, it is possible to satisfy the requirements and still address these subobjects. For example:

  extern constexpr int x[] = { 0, 1 };
  constexpr const int *p1 = x + 1;
  const int &r = *p1;

  template <const int *> struct A;
  template <> struct A<&r> { };

If this is intentional, the note in 13.4.3 [temp.arg.nontype] paragraph 3 should be revised or removed; if not, the normative wording of paragraph 1 must be revised.

History
Date User Action Args
2014-11-24 00:00:00adminsetstatus: drwp -> c++14
2014-03-03 00:00:00adminsetstatus: dr -> drwp
2013-10-14 00:00:00adminsetmessages: + msg4699
2013-10-14 00:00:00adminsetstatus: tentatively ready -> dr
2013-09-03 00:00:00adminsetmessages: + msg4466
2013-09-03 00:00:00adminsetstatus: drafting -> tentatively ready
2013-05-03 00:00:00adminsetmessages: + msg4347
2013-05-03 00:00:00adminsetstatus: open -> drafting
2012-02-06 00:00:00admincreate