2016-10-23 17 views
12

Trong một answer đểSự khác nhau giữa biến thể :: biến thể và tăng :: là gì?

What is the equivalent of boost::variant in the C++ standard library?

nó được đề cập rằng boost::variantstd::variant khác nhau một chút.

  • Sự khác biệt, cho đến khi ai đó sử dụng các lớp này là có liên quan?
  • Ủy ban thể hiện động lực nào để áp dụng std::variant với những khác biệt này?
  • Tôi nên theo dõi điều gì khi mã hóa một trong hai cách này, để duy trì khả năng tương thích tối đa với việc chuyển sang chế độ khác?

(động cơ đang sử dụng boost::variant trong pre-C++ 17)

+0

@JohnZwinck: Sẽ đánh giá cao nhận xét của bạn/câu trả lời như thế nào khi nhìn thấy bạn viết rằng câu trả lời tôi liên kết với. – einpoklum

+5

Tôi nghĩ rằng JohnZwinck sẽ không được thông báo trừ khi anh ấy tương tác với câu hỏi này. Bạn có thể nhận xét về câu trả lời của mình cho câu hỏi khác thay vào đó để thu hút sự chú ý của anh ấy. – DavidW

Trả lời

3

Có vẻ như những điểm chính của tranh chấp liên quan đến việc thiết kế một lớp biến thể đã được những gì sẽ xảy ra khi một bài tập để các biến thể , mà nên sau khi hoàn thành phá tan những giá trị cũ, ném một ngoại lệ:

variant<std::string, MyClassWithThrowingDefaultCtor> v = "ABC"; 
v = MyClassWithThrowingDefaultCtor(); 

các tùy chọn dường như là:

  • Ngăn chặn điều này bằng cách hạn chế các loại có thể thể hiện được đối với các kiểu không thể di chuyển được.
  • Giữ giá trị cũ - nhưng điều này yêu cầu bộ đệm đôi (nghĩa là boost::variant hiển nhiên).
  • Có trạng thái 'thảnh thơi' không có giá trị cho mỗi biến thể và chuyển đến trạng thái đó trên các lỗi như vậy.
  • hành vi Undefined
  • Hãy ném biến khi cố gắng đọc giá trị của nó sau khi một cái gì đó giống như điều đó xảy ra

và nếu tôi không nhầm, sau này là những gì được chấp nhận.

này được tóm tắt từ ISO C++ trên blog post bởi Axel Naumann từ Tháng Mười Một 2015.

13
  • hành vi chuyển nhượng/emplacement:

    • boost::variant thể allocate memory when performing assignment thể thành live variant. Có a number of rules that govern when this can happen, do đó, cho dù boost::variant sẽ phân bổ bộ nhớ phụ thuộc vào Ts nó được khởi tạo với.

    • std::variant sẽ không bao giờ phân bổ động bộ nhớ. Tuy nhiên, như một sự nhượng bộ đối với các quy tắc phức tạp của các đối tượng C++, nếu một phép gán/vị trí ném, thì variantcó thể nhập trạng thái "valueless_by_exception". Trong trạng thái này, không thể truy cập variant cũng như bất kỳ chức năng nào khác để truy cập vào một công việc thành viên cụ thể.

      Bạn chỉ có thể nhập trạng thái này nếu chuyển nhượng/vị trí ném.

  • Boost.Variant bao gồm recursive_variant, trong đó allows a variant to contain itself. Về cơ bản chúng là các trình bao bọc đặc biệt xung quanh một con trỏ đến một số boost::variant, nhưng chúng được gắn vào máy móc truy cập.

    std::variant không có loại trình trợ giúp như vậy.

  • std::variant cung cấp thêm sử dụng các tính năng sau C++ 11. Ví dụ:

+0

Có thể thêm loại chức năng đệ quy này vào 'std :: variant' mà không thay đổi lớp không? (Nhưng có lẽ với việc thêm nội dung vào 'namespace std'?) – einpoklum

+0

@einpoklum: Điểm của' recursive_variant' là nó cho phép 'visit' tự động giải nén và truy cập đối tượng mà nó tham chiếu. Vì vậy, bạn sẽ phải xây dựng máy móc đó thành 'std :: visit'. Điều này là không thể nếu không có * thay thế * 'std :: visit', mà bạn không thể làm. Tất nhiên, bạn luôn có thể tạo phiên bản 'std :: visit' của riêng bạn trong không gian tên của riêng bạn, thực hiện việc giải nén/truy cập. –

+0

Tôi tự hỏi nếu nó đang được xem xét để thêm 'recursive_variant' vào phiên bản' std' ... ít nhất bây giờ tôi đang sử dụng các biến thể nặng nề, có vẻ như có thể làm cho chúng đệ quy đại diện cho sức mạnh của chúng. –

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