NULL
Section: 23.2.4 [sequence.reqmts] Status: C++11 Submitter: Matt Austern Opened: 2009-10-09 Last modified: 2016-01-28
Priority: Not Prioritized
View other active issues in [sequence.reqmts].
View all other issues in [sequence.reqmts].
View all issues with C++11 status.
Discussion:
On g++ 4.2.4 (x86_64-linux-gnu), the following file gives a compile error:
#include <vector> void foo() { std::vector<int*> v(500L, NULL); }
Is this supposed to work?
The issue: if NULL
happens to be defined as 0L
, this is an invocation of
the constructor with two arguments of the same integral type.
23.2.4 [sequence.reqmts]/14
(N3035)
says that this will behave as if the overloaded constructor
X(size_type, const value_type& = value_type(), const allocator_type& = allocator_type())
were called instead, with the arguments
static_cast<size_type>(first)
, last
and
alloc
, respectively. However, it does not say whether this
actually means invoking that constructor with the exact textual form of
the arguments as supplied by the user, or whether the standard permits
an implementation to invoke that constructor with variables of the same
type and value as what the user passed in. In most cases this is a
distinction without a difference. In this particular case it does make a
difference, since one of those things is a null pointer constant and the
other is not.
Note that an implementation based on forwarding functions will use the latter interpretation.
[ 2010 Pittsburgh: Moved to Open. ]
[ 2010-03-19 Daniel provides wording. ]
- Adapts the numbering used in the discussion to the recent working paper N3035.
- Proposes a resolution that requires implementations to use sfinae-like means to possibly filter away the too generic template c'tor. In fact this resolution is equivalent to that used for the
pair-NULL
problem (811), the only difference is, that issue 1234 was already a C++03 problem.This issue can be considered as a refinement of 438.
[ Post-Rapperswil ]
Wording was verified to match with the most recent WP. Jonathan Wakely and Alberto Barbati observed that the current
WP has a defect that should be fixed here as well: The functions signatures fx1
and fx3
are
incorrectly referring to iterator
instead of const_iterator
.
Moved to Tentatively Ready with revised wording after 7 positive votes on c++std-lib.
[ Adopted at 2010-11 Batavia ]
Proposed resolution:
Change 23.2.3 [sequence.reqmts]/14+15 as indicated:
14 For every sequence container defined in this Clause and in Clause 21:
If the constructor
template <class InputIterator> X(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())is called with a type
InputIterator
that does not qualify as an input iterator, then the constructor shall not participate in overload resolution.will behave as if the overloaded constructor:X(size_type, const value_type& = value_type(), const allocator_type& = allocator_type())
were called instead, with the arguments.static_cast<size_type>(first)
,last
andalloc
, respectivelyIf the member functions of the forms:
template <class InputIterator> // such as insert() rt fx1(const_iterator p, InputIterator first, InputIterator last); template <class InputIterator> // such as append(), assign() rt fx2(InputIterator first, InputIterator last); template <class InputIterator> // such as replace() rt fx3(const_iterator i1, const_iterator i2, InputIterator first, InputIterator last);are called with a type
InputIterator
that does not qualify as an input iterator, then these functions shall not participate in overload resolution.will behave as if the overloaded member functions:rt fx1(iterator, size_type, const value_type&);rt fx2(size_type, const value_type&);rt fx3(iterator, iterator, size_type, const value_type&);
were called instead, with the same arguments.
15 In the previous paragraph the alternative binding will fail iffirst
is not implicitly convertible toX::size_type
or iflast
is not implicitly convertible toX::value_type
.