- Title
- Multiple default constructor templates
- Status
- cd4
- Section
- 9.5 [dcl.init]
- Submitter
- Nikolay Ivchenkov
Created on 2013-03-01.00:00:00 last changed 116 months ago
Messages
Date: 2014-11-15.00:00:00
[Moved to DR at the November, 2014 meeting.]
Date: 2014-06-15.00:00:00
Proposed resolution (June, 2014): Change 6.3 [basic.def.odr] paragraph 3 as follows: Change 9.5 [dcl.init] paragraph 7 as follows: To default-initialize an object of type T means:
Change 11.4.5 [class.ctor] paragraph 4 as follows: Change 12.2 [over.match] bullet 2.4 as
follows: Overload resolution selects the function to call in seven
distinct contexts within the language: ... invocation of a constructor for default- or
direct-initialization (9.5 [dcl.init]) of a class
object (12.2.2.4 [over.match.ctor]); ... Change 12.2.2.4 [over.match.ctor] paragraph 1 as follows:
...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.5 [dcl.init]. A constructor for a class is odr-used
as specified in 9.5 [dcl.init]. A destructor for a
class is odr-used if it is potentially invoked
(11.4.7 [class.dtor]).
if If T is a (possibly
cv-qualified) class type (Clause 11 [class]), the
default constructor (11.4.5 [class.ctor]) for T is
called (and the initialization is ill-formed if T has no
default constructor or overload resolution
(12.2 [over.match]) results in an ambiguity or in a
function that is deleted or inaccessible from the context of the
initialization); constructors are considered. The
applicable constructors are enumerated (12.2.2.4 [over.match.ctor]),
and the best one for the initializer () is chosen
through overload resolution (12.2 [over.match]). The
constructor thus selected is called, with an empty argument list, to
initialize the object.
if If T is an array type,
each element is
default-initialized;.
otherwise Otherwise, no initialization
is performed.
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...
When objects of class type are direct-initialized
(9.5 [dcl.init]),
or copy-initialized from
an expression of the same or a derived class type
(9.5 [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.
Date: 2013-03-01.00:00:00
It is unclear whether code like the following is supposed to be
supported or not: 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.
#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);
}
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2017-02-06 00:00:00 | admin | set | status: drwp -> cd4 |
| 2015-05-25 00:00:00 | admin | set | status: dr -> drwp |
| 2015-04-13 00:00:00 | admin | set | messages: + msg5380 |
| 2014-11-24 00:00:00 | admin | set | status: tentatively ready -> dr |
| 2014-07-07 00:00:00 | admin | set | messages: + msg5076 |
| 2014-07-07 00:00:00 | admin | set | status: drafting -> tentatively ready |
| 2013-05-03 00:00:00 | admin | set | status: open -> drafting |
| 2013-03-01 00:00:00 | admin | create | |