This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-12-19


1630. Multiple default constructor templates

Section: 9.4  [dcl.init]     Status: CD4     Submitter: Nikolay Ivchenkov     Date: 2013-03-01

[Moved to DR at the November, 2014 meeting.]

It is unclear whether code like the following is supposed to be supported or not:

  #include <iostream>
  #include <type_traits>

  #define ENABLE_IF(...) \
    typename std::enable_if<__VA_ARGS__, int>::type = 0
  #define PRINT_VALUE(...) \
    std::cout << #__VA_ARGS__ " = " << __VA_ARGS__ << std::endl

  struct undefined {};

  template <class T>
    undefined special_default_value(T *);

  template <class T>
    struct has_special_default_value :
      std::integral_constant
      <
        bool,
        !std::is_same
          <
            decltype(special_default_value((T *)0)),
            undefined
          >{}
      > {};

  template <class T> struct X {
    template <class U = T, ENABLE_IF(!has_special_default_value<U>{})>
      X() : value() {}
    template <class U = T, ENABLE_IF(has_special_default_value<U>{})>
      X() : value(special_default_value((T *)0)) {}
    T value;
  };

  enum E {
    e1 = 1,
    e2 = 2
  };

  E special_default_value(E *) { return e1; }

  int main() {
    X<int> x_int;
    X<E> x_E;
    PRINT_VALUE(x_int.value);
    PRINT_VALUE(x_E.value);

    PRINT_VALUE(X<int>().value);
    PRINT_VALUE(X<E>().value);
  }

The intent is that X<int> should call the first default constructor and X<E> should call the second.

If this is intended to work, the rules for making it do so are not clear; current wording reads as if a class can have only a single default constructor, and there appears to be no mechanism for using overload resolution to choose between variants.

Proposed resolution (June, 2014):

  1. Change 6.3 [basic.def.odr] paragraph 3 as follows:

  2. ...An assignment operator function in a class is odr-used by an implicitly-defined copy-assignment or move-assignment function for another class as specified in 11.4.5.3 [class.copy.ctor]. A default constructor for a class is odr-used by default initialization or value initialization as specified in 9.4 [dcl.init]. A constructor for a class is odr-used as specified in 9.4 [dcl.init]. A destructor for a class is odr-used if it is potentially invoked (11.4.7 [class.dtor]).
  3. Change 9.4 [dcl.init] paragraph 7 as follows:

  4. To default-initialize an object of type T means:

  5. Change 11.4.5 [class.ctor] paragraph 4 as follows:

  6. A default constructor for a class X is a constructor of class X that can be called without an argument either has no parameters or else each parameter that is not a function parameter pack has a default argument. If there is no user-declared constructor...
  7. Change 12.2 [over.match] bullet 2.4 as follows:

  8. Overload resolution selects the function to call in seven distinct contexts within the language:

  9. Change 12.2.2.4 [over.match.ctor] paragraph 1 as follows:

  10. When objects of class type are direct-initialized (9.4 [dcl.init]), or copy-initialized from an expression of the same or a derived class type (9.4 [dcl.init]), or default-initialized, overload resolution selects the constructor. For direct-initialization or default-initialization, the candidate functions are all the constructors of the class of the object being initialized. For copy-initialization, the candidate functions are all the converting constructors (11.4.8.2 [class.conv.ctor]) of that class. The argument list is the expression-list or assignment-expression of the initializer.


pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy