应该`unique_ptr< T const [] >` 接受 `T*` 构造函数参数吗?

发布于 2024-12-21 07:25:31 字数 1717 浏览 4 评论 0 原文

代码:

#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
}

Visual C++ 10.0 和 MinGW g++ 4.4.1 的示例错误:

[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::unique_ptr<_Ty>'
        with
        [
            _Ty=const T []
        ]
        C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2509) : see declaration of 'std::unique_ptr<_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 main()':
c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:379: error: deleted function '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]
> _

在我看来,数组版本应该接受与非数组版本相同的隐式常量添加。

不同之处在于,数组版本不应接受指向派生类的指针,这显然是上面启动的机制。

代码有效吗?

如果代码在形式上无效,标准的措辞是否反映了意图(即 DR 是否合适)?

如果第一个答案为“否”,第二个答案为“是”,则意图是否有缺陷(即,DR 是否合适)?

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
}

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

[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::unique_ptr<_Ty>'
        with
        [
            _Ty=const T []
        ]
        C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2509) : see declaration of 'std::unique_ptr<_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 main()':
c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:379: error: deleted function '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]
> _

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)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉酒的小男人 2024-12-28 07:25:31

缺陷报告可能是合适的。 §20.7.1.3.1 说,

explicit unique_ptr(pointer p) noexcept;
unique_ptr(pointer p, see below d) noexcept;
unique_ptr(pointer p, see below d) noexcept;

这些构造函数的行为与主模板中的相同,只是它们不接受可转换为指针的指针类型。 [注意:一种实现技术是创建这些成员的私有模板化重载。 ——尾注]

这个想法显然是为了防止不适用于数组的派生到基数转换。但这是不具体的,并且简历资格转换也被禁止。也许应该将其更改为禁止指针转换(第4.10节),而不是所有指针转换。

A defect report may be appropriate. §20.7.1.3.1 says,

explicit unique_ptr(pointer p) noexcept;
unique_ptr(pointer p, see below d) noexcept;
unique_ptr(pointer p, see below d) noexcept;

These constructors behave the same as in the primary template except that they do not accept pointer types which are convertible to pointer. [Note: One implementation technique is to create private templated overloads of these members. — end note ]

The idea is clearly to prevent derived-to-base conversions that don't work with arrays. But it is unspecific and cv-qualification conversion is forbidden too. Perhaps it should be changed to forbid pointer conversions (§4.10), not all conversions of pointers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文