This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 1234. "Do the right thing" and `NULL`

Section: 22.2.3 [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. 22.2.3 [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` 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`.