Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofC++17 status.

2367.pair andtuple are not correctly implemented foris_constructible with no args

Section: 21.3.6.4[meta.unary.prop]Status:C++17Submitter: Howard HinnantOpened: 2014-02-19Last modified: 2017-07-30

Priority:3

View otheractive issues in [meta.unary.prop].

View all otherissues in [meta.unary.prop].

View all issues withC++17 status.

Discussion:

Consider:

struct X{  X() = delete;};int main(){  typedef std::pair<int, X> P;  static_assert(!std::is_constructible<P>::value, "");  static_assert(!std::is_default_constructible<P>::value, "");  typedef std::tuple<int, X> T;  static_assert(!std::is_constructible<T>::value, "");  static_assert(!std::is_default_constructible<T>::value, "");}

For me thesestatic_asserts fail. And worse than that, even asking the question fails (as opposed to gets the wrong answer):

assert(!std::is_constructible<P>::value);

In file included from test.cpp:2:

error:      call to deleted constructor of 'X'   pair() : first(), second() {}                     ^note: function has been explicitly marked deleted here    X() = delete;    ^1 error generated.

This can be solved by specializingis_constructible onpair andtuple for zero Args:

template <class T, class U>struct is_constructible<pair<T, U>>  : integral_constant<bool, is_default_constructible<T>::value &&                            is_default_constructible<U>::value>{};template <class ...T>struct is_constructible<tuple<T...>>  : integral_constant<bool,                      __all<is_default_constructible<T>::value...>::value>{};

Now everything just works.

[2014-05-14, Daniel comments]

The proposed resolution is incomplete, because it wouldn't work forcv-qualified objects ofpair or for references of them during reference-initialization.

I would like to point out that the approach suggested inN3739can be easily extended to solve the problem without need to muddle with specializingis_constructible:

template<class U1 = T1, class U2 = T2,  typename enable_if<    is_default_constructible<U1>::value && is_default_constructible<U2>::value  , bool>::type = false>constexpr pair();

The new wording proposal represents an alternative wording change that I would strongly prefer.

Previous resolution from Howard [SUPERSEDED]:

This wording is relative to N3936.

  1. Add to 22.3.3[pairs.spec]:

    template <class T, class U>struct is_constructible<pair<T, U>>  : integral_constant<bool, is_default_constructible<T>::value &&                            is_default_constructible<U>::value>{};
  2. Add to 22.4.12[tuple.special]:

    template <class ...T>struct is_constructible<tuple<T...>>  : integral_constant<bool,see below>{};

    -?- The second argument tointegral_constant shall be true if for eachT,is_default_constructible<T>::value is true.

[2015-05, Lenexa]

STL: I object to this resolution due to British spelling of behavior
JW: we already have other places of this spelling
VV: the easy resolution is to remove the notes
MC: if that's all we want to change: put it in and make the editorial change of removing the note
VV: the other paper doesn't make any of these changes so it would be consistent
JW: this make me want even more the features of having constructors doing the Right Thing- I haven't written up the request to do something like that
VV: so it would be an aggregate reflecting the properties of the constituting types
JW: I should write that up
MC: any objection to move to ready? in favor: 16, opposed: 0, abstain: 1

Proposed resolution:

This wording is relative to N3936.

  1. Change 22.3.2[pairs.pair] around p3 as indicated:

    constexpr pair();

    -3-Requires:is_default_constructible<first_type>::value is true andis_default_constructible<second_type>::value is true.

    -4-Effects: Value-initializes first and second.

    -?-Remarks: This constructor shall not participate in overload resolution unlessis_default_constructible<first_type>::value is true andis_default_constructible<second_type>::value is true. [Note: This behaviour can be implementedby a constructor template with default template arguments —end note].

  2. Change 22.4.4.2[tuple.cnstr] around p4 as indicated:

    constexpr tuple();

    -4-Requires:is_default_constructible<Ti>::value is true for alli.

    -5-Effects: Value initializes each element.

    -?-Remarks: This constructor shall not participate in overload resolution unlessis_default_constructible<Ti>::value is true for alli. [Note: This behaviour can be implemented by a constructor template with default template arguments —end note].


[8]ページ先頭

©2009-2026 Movatter.jp