Should `unique_ptr< T const [] >` accept a `T*` constructor argument?

Discussion in 'C++' started by Alf P. Steinbach, Dec 16, 2011.

  1. <code>
    #include <memory>
    using namespace std;

    struct T {};

    T* foo() { return new T; }
    T const* bar() { return foo(); }

    int main()
    {
    unique_ptr< T const > p1( bar() ); // OK
    unique_ptr< T const [] > a1( bar() ); // OK

    unique_ptr< T const > p2( foo() ); // OK
    unique_ptr< T const [] > a2( foo() ); // ? this is line #15
    }
    </code>


    Example errors with Visual C++ 10.0 and MinGW g++ 4.4.1:


    <example>
    [d:\dev\test]
    > cl foo.cpp

    foo.cpp
    foo.cpp(15) : error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot
    access private member declared in class 'std::uni
    que_ptr<_Ty>'
    with
    [
    _Ty=const T []
    ]
    C:\Program Files (x86)\Microsoft Visual Studio
    10.0\VC\INCLUDE\memory(2509) : see declaration of 'std::unique_pt
    r<_Ty>::unique_ptr'
    with
    [
    _Ty=const T []
    ]

    [d:\dev\test]
    > g++ foo.cpp -std=c++0x

    c:\program files
    (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:
    In function 'int mai
    n()':
    c:\program files
    (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:379:
    error: deleted f
    unction 'std::unique_ptr<_Tp [], _Tp_Deleter>::unique_ptr(_Up*, typename
    std::enable_if<std::is_convertible::value, void
    >::type*) [with _Up = T, _Tp = const T, _Tp_Deleter =

    std::default_delete<const T []>]'
    foo.cpp:15: error: used here

    [d:\dev\test]
    > _

    </example>


    It seems to me that the array version should accept the same implicit
    const-adding as the non-array version.

    The difference is that the array version should not accept pointer to a
    derived class, and that's the machinery that apparently kicks in above.

    Is the code valid?

    If the code is formally invalid, does the standard's wording reflect the
    intent (i.e., is a DR appropriate)?

    If no to the first and yes to the second, is the intent defective (i.e.,
    again, is a DR appropriate)?


    Cheers,

    - Alf
     
    Alf P. Steinbach, Dec 16, 2011
    #1
    1. Advertising

  2. Alf P. Steinbach

    Gil Guest

    On Dec 16, 2:59 am, "Alf P. Steinbach" <alf.p.steinbach
    > wrote:
    > <code>
    > #include <memory>
    > using namespace std;
    >
    > struct T {};
    >
    > T* foo() { return new T; }
    > T const* bar() { return foo(); }
    >
    > int main()
    > {
    >      unique_ptr< T const >       p1( bar() );        // OK
    >      unique_ptr< T const [] >    a1( bar() );        //OK
    >
    >      unique_ptr< T const >       p2( foo() );        // OK
    >      unique_ptr< T const [] >    a2( foo() );        //? this is line #15}
    >
    > </code>
    >
    > Example errors with Visual C++ 10.0 and MinGW g++ 4.4.1:
    >
    > <example>
    > [d:\dev\test]
    >  > cl foo.cpp
    > foo.cpp
    > foo.cpp(15) : error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot
    > access private member declared in class 'std::uni
    > que_ptr<_Ty>'
    >          with
    >          [
    >              _Ty=const T []
    >          ]
    >          C:\Program Files (x86)\Microsoft Visual Studio
    > 10.0\VC\INCLUDE\memory(2509) : see declaration of 'std::unique_pt
    > r<_Ty>::unique_ptr'
    >          with
    >          [
    >              _Ty=const T []
    >          ]
    >
    > [d:\dev\test]
    >  > g++ foo.cpp -std=c++0x
    > c:\program files
    > (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:
    > In function 'int mai
    > n()':
    > c:\program files
    > (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:379:
    > error: deleted f
    > unction 'std::unique_ptr<_Tp [], _Tp_Deleter>::unique_ptr(_Up*, typename
    > std::enable_if<std::is_convertible::value, void
    >  >::type*) [with _Up = T, _Tp = const T, _Tp_Deleter =
    > std::default_delete<const T []>]'
    > foo.cpp:15: error: used here
    >
    > [d:\dev\test]
    >  > _
    > </example>
    >
    > It seems to me that the array version should accept the same implicit
    > const-adding as the non-array version.
    >
    > The difference is that the array version should not accept pointer to a
    > derived class, and that's the machinery that apparently kicks in above.
    >
    > Is the code valid?
    >


    no

    > If the code is formally invalid, does the standard's wording reflect the
    > intent


    yes

    > (i.e., is a DR appropriate)?


    no

    >
    > If no to the first and yes to the second, is the intent defective (i.e.,
    > again, is a DR appropriate)?


    yes

    >
    > Cheers,
    >
    > - Alf


    read [unique.ptr.runtime.ctor].

    hth,
    Gil
     
    Gil, Dec 19, 2011
    #2
    1. Advertising

  3. On 19.12.2011 22:11, Gil wrote:
    > On Dec 16, 2:59 am, "Alf P. Steinbach"<alf.p.steinbach
    > > wrote:
    >> <code>
    >> #include<memory>
    >> using namespace std;
    >>
    >> struct T {};
    >>
    >> T* foo() { return new T; }
    >> T const* bar() { return foo(); }
    >>
    >> int main()
    >> {
    >> unique_ptr< T const> p1( bar() ); // OK
    >> unique_ptr< T const []> a1( bar() ); // OK
    >>
    >> unique_ptr< T const> p2( foo() ); // OK
    >> unique_ptr< T const []> a2( foo() ); // ? this is line #15}
    >>
    >> </code>
    >>
    >> Example errors with Visual C++ 10.0 and MinGW g++ 4.4.1:
    >>
    >> <example>
    >> [d:\dev\test]
    >> > cl foo.cpp

    >> foo.cpp
    >> foo.cpp(15) : error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot
    >> access private member declared in class 'std::uni
    >> que_ptr<_Ty>'
    >> with
    >> [
    >> _Ty=const T []
    >> ]
    >> C:\Program Files (x86)\Microsoft Visual Studio
    >> 10.0\VC\INCLUDE\memory(2509) : see declaration of 'std::unique_pt
    >> r<_Ty>::unique_ptr'
    >> with
    >> [
    >> _Ty=const T []
    >> ]
    >>
    >> [d:\dev\test]
    >> > g++ foo.cpp -std=c++0x

    >> c:\program files
    >> (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:
    >> In function 'int mai
    >> n()':
    >> c:\program files
    >> (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:379:
    >> error: deleted f
    >> unction 'std::unique_ptr<_Tp [], _Tp_Deleter>::unique_ptr(_Up*, typename
    >> std::enable_if<std::is_convertible::value, void
    >> >::type*) [with _Up = T, _Tp = const T, _Tp_Deleter =

    >> std::default_delete<const T []>]'
    >> foo.cpp:15: error: used here
    >>
    >> [d:\dev\test]
    >> > _

    >> </example>
    >>
    >> It seems to me that the array version should accept the same implicit
    >> const-adding as the non-array version.
    >>
    >> The difference is that the array version should not accept pointer to a
    >> derived class, and that's the machinery that apparently kicks in above.
    >>
    >> Is the code valid?
    >>

    >
    > no
    >
    >> If the code is formally invalid, does the standard's wording reflect the
    >> intent

    >
    > yes
    >
    >> (i.e., is a DR appropriate)?

    >
    > no
    >
    >>
    >> If no to the first and yes to the second, is the intent defective (i.e.,
    >> again, is a DR appropriate)?

    >
    > yes
    >
    > read [unique.ptr.runtime.ctor].


    Thanks for you comments, Gil.

    As it turned out, the code is invalid, but the standard's wording does
    not seem to have reflected the authors' intent.

    A DR has been filed, LWG 2118, <url:
    http://cplusplus.github.com/LWG/lwg-active.html#2118>. However a number
    of related issues (reset, deleter) popped up. Maybe a new DR will be
    opened for the combined total issue, I don't know.


    Cheers,

    - Alf
     
    Alf P. Steinbach, Dec 19, 2011
    #3
  4. Alf P. Steinbach

    SG Guest

    On 19 Dez., 22:59, Alf P. Steinbach wrote:
    >
    > A DR has been filed, LWG 2118, <url:http://cplusplus.github.com/LWG/lwg-active.html#2118>.
    > However a number of related issues (reset, deleter) popped up. Maybe a new DR will be
    > opened for the combined total issue, I don't know.


    FWIW, you have my support. I agree that the current wording is a bit
    over-eager with respect to disabling pointer type conversions. The
    intention is probably to avoid pointer arithmetic bugs in inheritance
    hierarchies.
     
    SG, Dec 20, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Javier
    Replies:
    2
    Views:
    618
    James Kanze
    Sep 4, 2007
  2. Aaron Graham

    where is unique_ptr?

    Aaron Graham, Jun 20, 2008, in forum: C++
    Replies:
    1
    Views:
    662
    Ed Smith-Rowland
    Jun 22, 2008
  3. fungus
    Replies:
    13
    Views:
    942
    fungus
    Oct 31, 2008
  4. Christopher
    Replies:
    5
    Views:
    1,489
    Thomas J. Gritzan
    Mar 18, 2009
  5. SG
    Replies:
    1
    Views:
    534
    Christopher
    Mar 17, 2009
Loading...

Share This Page