13

コード:

#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:\開発\テスト]
> cl foo.cpp
foo.cpp
foo.cpp(15): エラー C2248: 'std::unique_ptr<_Ty>::unique_ptr': クラス 'std::unique_ptr<_Ty>' で宣言されたプライベート メンバーにアクセスできません
        と
        [
            _Ty=const T []
        ]
        C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\memory(2509) : 'std::unique_ptr<_Ty>::unique_ptr' の宣言を参照してください
        と
        [
            _Ty=const T []
        ]

[d:\開発\テスト]
> 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: 関数 'int main()' 内:
c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:379: エラー: 削除された関数 '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: エラー: ここで使用

[d:\開発\テスト]
> _

配列バージョンは、非配列バージョンと同じ暗黙の const 追加を受け入れる必要があるように思えます。

違いは、配列バージョンが派生クラスへのポインターを受け入れてはならないことであり、それが明らかに上で作動する機構です。

コードは有効ですか?

コードが正式に無効である場合、標準の文言はその意図を反映していますか (つまり、DR は適切ですか)?

最初の質問が「いいえ」で、2 番目の回答が「はい」の場合、意図に欠陥がありますか (つまり、DR は適切ですか)?

4

1 に答える 1

9

欠陥レポートが適切な場合があります。§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;

これらのコンストラクターは、ポインターに変換可能なポインター型を受け入れないことを除いて、プライマリ テンプレートと同じように動作します。[注: 1 つの実装手法は、これらのメンバーのプライベート テンプレート オーバーロードを作成することです。— 終了注記]

アイデアは明らかに、配列では機能しない派生からベースへの変換を防ぐことです。しかし、それは不特定であり、cv-qualification 変換も禁止されています。おそらく、ポインターのすべての変換ではなく、ポインターの変換(§4.10)を禁止するように変更する必要があります。

于 2011-12-16T08:29:03.043 に答える