text: This document contains the C++ core language issues for which the Committee (J16 + WG21) has decided that no action is required, that is, issues with status "NAD" ("Not A Defect"), "dup" (duplicate), "concepts,"4606..
  Bullet 13.3 of _N4567_.
  According to 1.10 [intro.multithread] paragraph 24,]
  Some programmers find this liberty afforded to implementations to be disadvantageous; see this blog post for a discussion of the subject..
  There is a discrepancy between the syntaxes allowed for defining a constructor and a destructor of a class template. For example:
  template <class> struct S { S(); ~S (); }; template <class T> S<T>::S<T>() { } // error template <class T> S<T>::~S<T>() { } // okay
  The reason for this is that 3.4.3.1 [class.qual] paragraph 2 says that S::S is “considered to name the constructor,” which is not a template and thus cannot accept a template argument list. On the other hand, the second S in S::~S finds the injected-class-name, which “can be used with or without a template-argument-list” (14.6.1 [temp.local] paragraph 1) and thus satisfies the requirement to name the destructor's class (12.4 [class.dtor] paragraph 1).
  Would it make sense to allow the template-argument-list in the constructor declaration and thus make the language just a little easier to use?
  Rationale (July, 2007):
  The CWG noted that the suggested change would be confusing in the case where the class template had both template and non-template constructors.
  3.5 [basic.link] paragraph 8 says,
  A name with no linkage (notably, the name of a class or enumeration declared in a local scope (3.3.3 [basic.scope.block] )).3 [basic.scope..7.1 [dcl.type.cv] paragraph 4 already forbids modifying a const member of a POD struct. The prohibition need not be repeated in 3.9 [basic.types]..)
  Rationale (June, 2008):
  A copy constructor takes a reference as its first parameter, thus no user-declared copy constructor can be constexpr. 6 states,
  As described below, bool values behave as integral types.
  This sentence looks definitely out of order: how can a value behave as a type?
  Suggested resolution:
  Remove the sentence entirely, as it doesn't supply anything that isn't already stated in the following paragraphs and in the referenced section about integral promotion.
  Rationale (July, 2007):
  This is, at most, an editorial issue with no substantive impact. The suggestion has been forwarded to the project editor for consideration..
  Paragraph 3 of section 4.2.
  There is no normative requirement regarding the ability of floating-point values to represent integer values exactly; however, 4..11 .
  5.1.5 [expr.prim.lambda] paragraph 2 says,
  A closure object behaves as a function object (20.14 [function.objects])...
  This linkage to <functional> increases the dependency of the language upon the library and is inconsistent with the definition of “freestanding” in 17.6.1.3 [compliance].
  Rationale (July, 2009):
  The reference to 20.14 [function.objects] appears in a note, not in normative text, and is intended only to clarify the meaning of the term “function object.” The CWG does not believe that this reference creates any dependency on any library facility..
  Rationale (October, 2009):
  The consensus of the CWG was that this is not a sufficiently important problem to warrant changing the existing specification.
  According to 5.1.5 .5 .5 ...
  According to 5.2.1 [expr.sub] paragraph 11,
  No entity is captured by an init-capture.
  It should be made clearer that a variable, odr-used by an init-capture in a nested lambda, is still captured by the containing lambda as a result of the init-capture.
  Rationale (October, 2015):
  Subsequent edits have removed the offending phraseXS.
  Should the determination of array bounds from an initializer, described in 8.
  .
  Note (March, 2008):
  The Evolution Working Group recommended closing this issue with no further consideration. See paper J16/07-0033 = WG21 N2173..
  In 5.3.1 [expr.unary.op], part of paragraph 7 describes how to compute the negative of an unsigned quantity:
  The negative of an unsigned quantity is computed by subtracting its value from 2n, where n is the number of bits in the promoted operand. The type of the result is the type of the promoted operand.
  According to this method, -0U will get the value 2n - 0 = 2n, where n is the number of bits in an unsigned int. However, 2n is obviously out of the range of values representable by an unsigned int and thus not the actual value of -0U. To get the result, a truncating conversion must be applied.
  Rationale (April, 2007):
  As noted in the issue description, a “truncating conversion” is needed. This conversion is supplied without need of an explicit mention, however, by the nature of unsigned arithmetic given in 3.9.1 [basic.fundamental] paragraph 4:
  Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.
  The standard forbids a lambda from appearing in a sizeof operand:
  A lambda-expression shall not appear in an unevaluated operand (Clause 5 [expr]).
  (5.1.5 [expr.prim.lambda] paragraph 2). However, there appears to be no prohibition of the equivalent usage when a variable or data member has a closure class as its type:
  int main() { int i = 1; int j = 1; auto f = [=]{ return i + j;}; return sizeof(f); }
  According to 5.1.5 .
  The relational operators have unspecified results when comparing pointers that refer to objects that are not members of the same object or elements of the same array (5.9 [expr.rel] paragraph 2, second bullet). This restriction (which dates from C89) stems from the desire not to penalize implementations on architectures with segmented memory by forcing them essentially to simulate a flat address space for the purpose of these comparisons. If such an implementation requires that objects and arrays to fit within a single segment, this restriction enables pointer comparison to be done simply by comparing the offset portion of the pointers, which could be much faster than comparing the full pointer values.
  The problem with this restriction in C++ is that it forces users of the Standard Library containers to use less<T*> instead of the built-in < operator to provide a total ordering on pointers, a usage that is inconvenient and error-prone. Can the existing restriction be relaxed in some way to allow the built-in operator to provide a total ordering? (John Spicer pointed out that the actual comparison for a segmented architecture need only supply a total ordering of pointer values, not necessarily the complete linearization of the address space.)
  Rationale (April, 2007):
  The current specification is clear and was well-motivated. Analysis of whether this restriction is still needed should be done via a paper and discussed in the Evolution Working Group rather than being handled by CWG as an issue/defect..
  Consider:
  int* p = false; // Well-formed? int* q = !1; // What about this?>From 3.9.1 [basic.fundamental] paragraph 6: "As described below, bool values behave as integral types."
  From 4.11 [conv.ptr] paragraph 1: "A null pointer constant is an integral constant expression rvalue of integer type that evaluates to zero."
  From 5 type.]), [intro.defs]  in that translation unit.
  Rationale (October, 2004):
  CWG felt that readers might misunderstand “declaration” as meaning “non-definition declaration.”.
  9.
  7.1.1 [dcl.stc] paragraph 7 seems out of place in the current organization of the Standard::.....6.4.6 [replacement.functions], 18.6.2.1 [new.delete.single] par 2, and 3.7.4 [basic.stc.dynamic] par 2-3. I don't see anything explicitly saying that the replacement function may not be inline. The closest I can find is 18.6.2.1 ...2.2.1 [class.this] paragraph 1 allows use of this only in the body of a non-static member function, and the return type is not part of the function-body.
  Do we want to change the rules to allow these kinds of decltype expressions?
  Rationale (February, 2008):
  In the other cases where a class type is considered complete within the definition of the class, it is possible to defer handling the construct until the end of the definition. That is not possible for types, as the type may be needed immediately in subsequent declarations.
  It was also noted that the primary utility of decltype is in generic contexts; within a single class definition, other mechanisms are possible (e.g., use of a member typedef in both the declaration of the operand of the decltype and to replace the decltype itself).
  The first bullet of 7.1.7.2 [dcl.type.simple] paragraph 4 says,
  There are two clarifications to this specification that would assist the reader. First, it would be useful to have a note highlighting the point that a parenthesized expression is neither an id-expression nor a member access expression.
  Second, the phrase “the type of the entity named by e” is unclear as to whether cv-qualification in the object or pointer expression is or is not part of that type. Rephrasing this to read, “the declared type of the entity,” or adding “(ignoring any cv-qualification in the object expression or pointer expression),” would clarify the intent.
  Rationale (February, 2008):
  The text is clear enough. In particular, both of these points are illustrated in the last two lines of the example contrasting decltype(a->x) and decltype((a->x)): in the former, the expression has no parentheses, thus satisfying the requirements of the first bullet and yielding the declared type of A::x, while the second has parentheses, falling into the third bullet and picking up the const from the object expression in the member access.
  Because type deduction for the auto specifier is described in 7.1.
  Rationale (September, 2008):
  It is important that the deduction rules be the same in the function and auto cases. The result of this example might be surprising, but maintaining a consistent model for deduction is more important.
  An initializer list is treated differently in deducing the type of an auto specifier and in a function call. In 7.1.7.4 [dcl.spec.auto] paragraph 6, an initializer list is given special treatment so that auto is deduced as a specialization of std::initializer_list:
  Once the type of a declarator-id has been determined according to 8.3 [dcl.meaning], either a new invented type template parameter U or, if the initializer is a braced-init-list (8++..4.1 [basic.stc.dynamic.allocation] paragraph 1, 3.7.
  Rationale (July, 2009):
  The current specification does not restrict injection of names in elaborated-type-specifiers, and the consensus of the CWG was that no change is needed on this point...
  Note (March, 2008):
  The Evolution Working Group recommended closing this issue with no further consideration. See paper J16/07-0033 = WG21 N2173.
  .
  Note (March, 2008):
  The Evolution Working Group recommended closing this issue with no further consideration. See paper J16/07-0033 = WG21 N2173.)..
  The [[noreturn]] attribute, as specified in 7.6.8 ..
  According to 8.3.4 [dcl.array] paragraph 1,
  In a declaration T D where D has the form
  D1 [ constant-expressionopt ] attribute-specifieropt
  and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is an array type; if the type of the identifier of D contains the auto type-specifier, the program is ill-formed.
  This.6.3 [dcl.init.ref] paragraph 3 for function types. _N4567_.
  In section 8.
  According to the logic in 8.6.3 [dcl.init.ref] paragraph 5 as follows:
  ...
  If the initializer expression is a string literal (2.6 [dcl.init] and follow the logic ladder there with the element,” the logical result is that an initializer for a scalar could be arbitrarily deeply nested in braces, with each trip through the 8.6 [dcl.init] / 8.6.4 [dcl.init.list] recursion peeling off one layer. Presumably that is not intended.
  Rationale (October, 2012):
  The wording “a single element of type E” excludes the case of a nested braced initializer, because such an element has no type.
  If an initializer_list object is copied and the copy is elided, is the lifetime of the underlying array object extended? E.g.,
  void f() { std::initializer_list<int> L = std::initializer_list<int>{1, 2, 3}; // Lifetime of array extended? }
  The current wording is not clear.
  (See also issue 1299.)
  Notes from the October, 2012 meeting:
  The consensus of CWG was that the behavior should be the same, regardless of whether the copy is elided or not.
  Rationale (November, 2016):
  With the adoption of paper P0135R1, there is no longer any copy in this example to be elided.
  According to 8.
  [Detailed description pending.]
  Rationale (November, 2016):
  The reported issue is no longer relevant to the current working paper..2.
  Another instance to consider is that of invoking a member function from a null pointer:
  struct A { void f () { } }; int main () { A* ap = 0; ap->f (); }
  Which is explicitly noted as undefined in 9.2.2 [class.mfct.non-static],.
  The current wording of 9.2 incorrect.
  9.2.1 [class.mfct] paragraph 5 says this about member functions defined lexically outside the class:
  the member function name shall be qualified by its class name using the :: operator
  9.2.3.2 [class.static.data] paragraph 2 says this about static data members:
  In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator
  I would have expected similar wording in 9.2.5 [class.nest] paragraph 3 for nested classes. Without such wording, the following seems to be legal (and is allowed by all the compilers I have):
  struct base { struct nested; }; struct derived : base {}; struct derived::nested {};
  Is this just an oversight, or is there some rationale for this behavior?
  Rationale (July, 2008):
  The wording in 9 [class] paragraph 10 (added by the resolution of issue 284, which was approved after this issue was raised).
  Is this legal? Should it be?
  struct E { union { struct { int x; } s; } v; };
  One compiler faults a type definition (i.e. of the anonymous struct) since it is in an anonymous union [9.
  Note (March, 2008):
  The Evolution Working Group recommended closing this issue with no further consideration. See paper J16/07-0033 = WG21 N2173.
  Can a member of a union be of a class that has a user-declared non-default constructor? The restrictions on union membership in 9.
  Rationale (August, 2011):
  As given in the preceding note.
  According to 9.4  _N4567_.
  After the adoption of the wording for extended friend declarations, we now have this new paragraph in 11 a friend declaration designates a (possibly cv-qualified) class type or a class template, that class or template is declared as a friend; otherwise, the friend declaration is ignored. [Example:...
  Rationale (September, 2008):
  The proposed extension is not needed. The template case can be handled simply by providing a template header:
  template <typename T> friendE..
  The current wording of the Standard does not make clear whether a special member function that is defaulted and implicitly deleted is trivial. Triviality is visible in various ways that don't involve invoking the function, such as determining whether a type is trivially copyable and determining the result of various type traits. It also factors into some ABI specifications.
  (See also issue 1734.)
  Notes from the June, 2014 meeting:
  CWG felt that deleted functions should be trivial. See also issue 1590.
  Additional note, November, 2014:
  See paper N4148..
  Consider the following example:
  template<typename T, T V, int n = sizeof(V)> using X = int[n]; template<typename T> void f(X<T, 0>*) {} void g() { f<char>(0); }
  Current implementations get confused here because they substitute V=0 into the default argument of X before knowing the type T and end up with f having type void (int (*)[sizeof(0)]), that is, the array bound does not depend on T. It's not clear what should happen here.
  Rationale (March, 2016):
  There is no problem with the specification, only with the implementations; the default argument for n is dependent because V has a dependent type....
  Note (March, 2008):
  The Evolution Working Group recommended closing this issue with no further consideration. See paper J16/07-0033 = WG21 N2173.. [intro.defs] “undefined behavior.”.7.4  .2.,
  template<class T> struct A { enum E : T; enum class S : T; }; template<> enum A<int>::E : int { eint }; // OK template<> enum class A<int>::S : int { sint }; // OK template<class T> enum A<T>::E : T { eT }; template<class T> enum class A<T>::S : T { sT }; template<> enum A<char>::E : int { echar }; // ill-formed, A<char>::E was instantiated // when A<char> was instantiated template<> enum class A<char>::S : int { schar }; // OK.
  It is not clear whether the following common practice is valid by the current rules:
  // foo.h template<typename T> struct X { int f(); // never defined }; // foo.cc #include "foo.h" template<> int X<int>::f() { return 123; } // main.cc #include "foo.h" int main() { return X<int>().f(); }
  Relevant rules include 14 [temp] paragraph 6,
  A function template, member function of a class template, variable template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated (14.7.1 [temp.inst]) unless the corresponding specialization is explicitly instantiated (14.7.2 [temp.explicit]) in some translation unit; no diagnostic is required.
  14.7.1 [temp.inst] paragraph 2,
  Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist...
  and 14.7.3 [temp.expl.spec] paragraph 6:
  If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined.
  The intent appears to be that the reference in main.cc violates two rules: it implicitly instantiates something for which no definition is provided and that is not explicitly instantiated elsewhere, and it also causes an implicit instantiation of something explicitly specialized in another translation unit without a declaration of the explicit specialization.
  Rationale (March, 2016):
  As stated in the analysis, the intent is for the example to be ill-formed, no diagnostic required...
  Rationale (February, 2008):
  In the absence of a compelling need, the CWG felt that it was better not to change the existing rules. Allowing this case could cause a quiet change to the meaning of a program, because attempting to create a pointer to a reference type is currently a deduction failure...8.2.4 [temp.deduct.partial] paragraph 5). This means that neither parameter type is at least as specialized as the other (paragraph 8).
  According to 14.).
  [Detailed description pending.]
  Rationale (November, 2016):
  The reported issue is no longer relevant after the adoption of paper P0490R0 at the November, 2016 meeting.
  [Detailed description pending.]
  Rationale (November, 2016):
  The reported issue is no longer relevant after the adoption of paper P0490R0 at the November, 2016 meeting..11 . 133...7 [depr.uncaught]..
  Rationale (September, 2008):
  It is unclear what effect the provision of “unique mappings” has or if a conforming program could detect the failure of an implementation to do so. There has been a significant effort to synchronize this clause with the corresponding section of the C99 Standard, and given the lack of perceptible impact of the proposed change, there is insufficient motivation to introduce a new divergence in the wording.
  According to 16.2 [cpp.include] paragraph 4,
  A preprocessing directive of the form
  # include pp-tokens new-line
  ..
  Rationale (October, 2008):
  It was noticed that issue 353, an exact duplicate of this one, was independently opened and resolved.
  According to..2.1 [class.mfct]) or static data member (9.2::*)[]);.
  It is not clear whether the following declaration is well-formed:
  struct S { int i; } s = { { 1 } };According to 8.6.1 [dcl.init.aggr] paragraph 2, a brace-enclosed initializer is permitted for a subaggregate of an aggregate; however, i is a scalar, not an aggregate. 8.6 [dcl.init] paragraph 13 says that a standalone declaration like
  int i = { 1 };is permitted, but it is not clear whether this says anything about the form of initializers for scalar members of aggregates.
  This is (more) clearly permitted by the C89 Standard.
  Rationale (May, 2008):
  Issue 632 refers to exactly the same question and has a more detailed discussion of the considerations involved.
  In an example like
  const int&r {1};
  the expectation is that this creates a temporary of type const int containing the value 1 and binds the reference to it. And it does, but along the way it creates two temporaries. The wording in 8.2.3.2 [class.static.data] paragraph 3 says,
  If a static data member is of const literal type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression..6.3 [dcl.init.ref] did have distinct bullets for converting to an “lvalue” and to an “rvalue;” we now have a bullet which is not exclusively one or the other.
  Possible fix
  Add reference to [13.3.1.6 [over.match.ref]] in 8.6.3 [dcl.init.ref] for direct binding to rvalue reference/const non-volatile via UDC.
  Remove redundent sentence referring to second SCS.
  Modify example to indicate operator int&() is not a candidate function.
  Clarify that the point from 8.
  Consider the following example:
  template<typename ...T> struct X { void f(); static int n; }; template<typename T, typename U> using A = T; template<typename ...T> void X<A<T, decltype(sizeof(T))>...>::f() {} template<typename ...T> void X<A<T, decltype(sizeof(T))>...>::n = 0; void g() { X<void>().f(); X<void>::n = 1; }
  Should this be valid? The best answer would seem to be to produce an error during instantiation, and that appears to be consistent with the current Standard wording, but there is implementation divergence.
  See also issue 2021.
  Rationale (May, 2015):
  This issue is a duplicate os issue 1979.
  The description of how the partial ordering of template functions is determined in 14.5..
  The example in 18.6.2.3 ..11  object type or a function type, and CV1 and CV2 are cv-qualifier-seqs, there exist candidate operator functions of the form
  CV12 T& operator->*(CV1 C1*, CV2 T C2::*);
  where CV12 is the union of CV1 and CV2.
  C1 and C2 should be effective class types (cf 5.5 [expr.mptr.oper] paragraph 3.
  Also, should the relationship between those two classes be expressed as std::SameType or std::DerivedFrom requirements?..).
  Rationale (July, 2009):
  This suggestion would need a full proposal and discussion by the EWG before the CWG could consider it..12 .5  by EWG. current wording of the Standard appears to permit code like
  void f(const char (&)[10]); void g() { f("123"); f({'a','b','c','\0'}); }
  creating a temporary array of ten elements and binding the parameter reference to it. This is controversial and should be reconsidered. (See issues 1058 and 1232.)
  Rationale (March, 2016):
  Whether to support creating a temporary array in such cases is a question of language design and thus should be?
  Current implementations ignore narrowing conversions during overload resolution, emitting a diagnostic if calling the selected function would involve narrowing. For example:
  struct s { long m }; struct ss { short m; }; void f( ss ); void f( s ); void g() { f({ 1000000 }); // Ambiguous in spite of narrowing for f(ss) }
  However, the current wording of 13.3.3.1.5 [over.ics.list] paragraph 7 says,
  Otherwise, if the parameter has an aggregate type which can be initialized from the initializer list according to the rules for aggregate initialization (8.6.1 [dcl.init.aggr]), the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion.
  In the example above, ss cannot be initialized from { 1000000 } because of the narrowing conversion, so presumably f(ss) should not be considered. If this is not the intended outcome, paragraph 7 should be restated in terms of having an implicit conversion sequence, as in, e.g., bullet 9.1, instead of a valid initialization.
  Rationale (March, 2016):
  This is a question of language design and thus more suited to consideration by EWG..