2011-12-16 37 views
13

Code:Nên `unique_ptr <T const []>` chấp nhận một đối số hàm tạo `T *`?

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

Ví dụ lỗi với Visual C++ 10.0 và 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] 
> _ 

Dường như với tôi rằng phiên bản mảng nên chấp nhận cùng ngầm const-thêm như không phiên bản -ray.

Sự khác biệt là phiên bản mảng không nên chấp nhận con trỏ đến lớp dẫn xuất, và đó là máy móc dường như đá ở trên.

Mã có hợp lệ không?

Nếu mã chính thức không hợp lệ, từ ngữ của tiêu chuẩn có phản ánh ý định (tức là, DR thích hợp) không?

Nếu không có câu hỏi đầu tiên và có cho câu thứ hai, mục đích có phải là lỗi (tức là, một lần nữa, là DR thích hợp) không?

Trả lời

9

Báo cáo lỗi có thể phù hợp. §20.7.1.3.1 nói,

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

Những nhà xây dựng cư xử giống như trong mẫu ban đầu ngoại trừ việc họ không chấp nhận loại con trỏ đó là chuyển đổi cho con trỏ. [Lưu ý: Một kỹ thuật thực hiện là tạo ra quá tải templated riêng của các thành viên này. - lưu ý kết thúc]

Ý tưởng rõ ràng là ngăn chặn chuyển đổi từ cơ sở đến không hoạt động với mảng. Nhưng nó là chuyển đổi không xác định và cv-qualification cũng bị cấm. Có lẽ nó phải được thay đổi để cấm chuyển đổi con trỏ (§4.10), không phải tất cả chuyển đổi của con trỏ.

+1

"loại con trỏ có thể chuyển đổi thành con trỏ" - và thực sự là nitpick, ngôn ngữ này có phẳng không chính xác không? 'pointer' là một kiểu con trỏ có thể chuyển đổi thành con trỏ (ví dụ khi mô tả các khái niệm, nếu một số hàm trả về kiểu" convertible to T ", nó không có nghĩa là nó không phải là T). Nhưng tôi không nghĩ rằng ý định là để ngoại trừ 'con trỏ' cũng như một con trỏ đến các loại có nguồn gốc ;-) –

+0

i posted difort riport để csC++, nhưng nó có thể mất một thời gian để xuất hiện ... vì vậy, chỉ cho thông tin, tôi cũng trích dẫn những gì tôi nghĩ là ý định/lý do trong §20.7.1.3/1 dấu gạch ngang thứ 2, "Con trỏ đến các kiểu bắt nguồn từ T bị từ chối bởi các nhà xây dựng, và bằng cách đặt lại" :-) –

+2

Điều này trông giống như một lỗi đối với tôi. Vui lòng theo dõi tại: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#submit_issue. Tôi đã thực hiện một giải pháp trong libC++ (http://libcxx.llvm.org/). Thật khó để có được quyền hơn tôi đoán! –

Các vấn đề liên quan