Title
"Do the right thing" and NULL
Status
c++11
Section
[sequence.reqmts]
Submitter
Matt Austern

Created on 2009-10-09.00:00:00 last changed 143 months ago

Messages

Date: 2013-01-25.00:32:44

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 and alloc, respectively.

  • If 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 if first is not implicitly convertible to X::size_type or if last is not implicitly convertible to X::value_type.

Date: 2013-01-25.00:32:44

[ Adopted at 2010-11 Batavia ]

Date: 2013-01-25.00:32:44

[ 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.

Date: 2010-03-19.00:00:00

[ 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.

Date: 2010-10-21.18:28:33

[ 2010 Pittsburgh: Moved to Open. ]

Date: 2013-01-25.00:32:44

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. [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.

History
Date User Action Args
2013-01-25 00:32:44adminsetmessages: + msg6357
2013-01-25 00:32:44adminsetmessages: + msg6356
2013-01-25 00:32:44adminsetstatus: open -> c++11
2010-10-21 18:28:33adminsetmessages: + msg1259
2010-10-21 18:28:33adminsetmessages: + msg1258
2010-10-21 18:28:33adminsetmessages: + msg1257
2009-10-09 00:00:00admincreate