Tại sao std :: constructor nguyên tử hoạt động khác nhau trong C ++ 14 và C ++ 17


19

Tôi đang làm việc trong một dự án với C ++ 11 và tôi đã thử theo mã

#include <atomic>

struct A {
    std::atomic_int idx = 1;

};

int main() {
    return 0;
}

Tôi gặp lỗi trình biên dịch

error: use of deleted function 'std::__atomic_base<_IntTp>::__atomic_base(const std::__atomic_base<_IntTp>&) [with _ITp = int]'
 std::atomic_int idx = 1;
                       ^

Kết quả tương tự là với C ++ 14. Khi tôi chuyển sang C ++ 17, nó hoạt động: Wandbox

Tôi đã kiểm tra cppreference cho sự khác biệt:

Nhưng không có sự khác biệt được ghi nhận giữa C ++ 14 và C ++ 17. Tại sao nó hoạt động với C ++ 17 mà không phải với C ++ 14?


Trình biên dịch / thư viện chuẩn / nền tảng nào bạn sử dụng?
Victor Gubin

@VictorGubin Tôi đã thử với Clang và GCC trên Linux (Wandbox). Tôi đã thử các phiên bản khác nhau.
Thomas Sablik

1
Bạn có thể đơn giản hóa MCVE thành một cục bộ trong main(hoặc bất kỳ hàm nào, không cần nó main), thay vì một hàm tạo cấu trúc. Clang đưa ra một thông báo lỗi tương tự, rõ ràng hơn là nó đang cố gắng sử dụng một hàm tạo sao chép bị xóa thay vì trình khởi tạo hoặc hàm tạo đơn giản: godbolt.org/z/SBGf9w với libc ++
Peter Cordes

@PeterCordes Tôi không chắc lỗi này có liên quan đến khởi tạo lớp hay không.
Thomas Sablik

3
Nhận cùng một thông báo lỗi cho một ví dụ tái tạo tối thiểu đơn giản hơn chứng tỏ nó không phải. Tôi cũng không chắc cho đến khi tôi thử nó.
Peter Cordes

Câu trả lời:


29

Bởi vì trong C ++ 17 có RVO được đảm bảo. Trong C ++ 14 câu lệnh giống Foo x = Foo(args)Foo x (args)kỹ thuật không giống nhau, nhưng chúng nằm trong C ++ 17.

struct Foo {
    Foo() = default;
    Foo(const Foo&) = delete;
};

int main() {
    // Works in C++17 and C++20, fails in C++14 and before
    Foo foo = Foo(); 
}

Bạn có thể đọc thêm về điều này tại đây: https://en.cppreference.com/w/cpp/lingu/copy_elision

Cụ thể là phần (since C++17):

T x = T (T (f ())); // chỉ một cuộc gọi đến hàm tạo mặc định của T, để khởi tạo x

Để làm cho mã C ++ 14 hoạt động, bạn có thể sử dụng

std::atomic_int idx { 1 };
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.