2015-04-22 15 views
6
#include <type_traits> 

struct test { 
    virtual void foo() noexcept = 0; 
}; 

struct test2 : test { 
    void foo() noexcept override final {} 
}; 

// fails 
static_assert(std::is_move_constructible<test>::value, "test not move constructible"); 
// succeeds 
static_assert(std::is_move_constructible<test2>::value, "test2 not move constructible"); 

(Live)
Theo cppreference.com (và như xa như tôi hiểu), test nên có một constructor chuyển ngầm tạo:làm các chức năng ảo thuần túy có ngăn cản các nhà thầu di chuyển được tạo ra ngầm không?

Các ngầm-tuyên bố hay mặc định constructor di chuyển cho lớp T là được định nghĩa là bị xóa trong bất kỳ điều nào sau đây là đúng:

  • T [= test] có các thành viên dữ liệu không tĩnh mà không thể di chuyển được (đã xóa, không thể tiếp cận hoặc không rõ ràng).
  • T có lớp cơ sở ảo hoặc trực tiếp không thể di chuyển được (đã xóa, không thể truy cập hoặc chuyển động không rõ ràng) constructors)
  • T có lớp cơ sở trực tiếp hoặc ảo với một destructor xóa hoặc không thể tiếp cận
  • T là một liên minh và có một thành viên biến với constructor sao chép không tầm thường
  • (cho đến khi C++ 14) T có một tổ chức phi thành viên dữ liệu -static hoặc một cơ sở trực tiếp hoặc ảo mà không có một nhà xây dựng di chuyển mà không thể sao chép một cách trivially.

Tại sao trình biên dịch không tạo ra hàm khởi động ẩn cho test? Bất kỳ lý do tại sao nó làm như vậy cho test2?

Trả lời

15

std::is_move_constructible kiểm tra xem loại có thể được tạo từ đối số giá trị hay không. test là loại lớp trừu tượng. Nó không thể được xây dựng ở tất cả, bất kể tranh luận.

+0

Điều này có nghĩa là 'test' có/có thể có một hàm khởi động ẩn, mặc dù nó là vô dụng đối với chính lớp đó? – dasdave

+3

@MartinD. Vâng. Trong thực tế, chúng ta biết nó, vì 'is_move_constructible ' là đúng. – Barry

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