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

A

Alf P. Steinbach

<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:


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 said:
::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
 
G

Gil

<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
 
A

Alf P. Steinbach

<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:

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 said:
::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
 
S

SG

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top