เหตุใด std :: atomic constructor จึงมีความแตกต่างใน C ++ 14 และ C ++ 17


19

ฉันทำงานในโครงการที่มี C ++ 11 และฉันลองใช้รหัสต่อไปนี้

#include <atomic>

struct A {
    std::atomic_int idx = 1;

};

int main() {
    return 0;
}

ฉันได้รับข้อผิดพลาดของคอมไพเลอร์

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

ผลลัพธ์เดียวกันคือกับ C ++ 14 เมื่อฉันเปลี่ยนเป็น C ++ 17 มันใช้งานได้: wandbox

ฉันตรวจสอบความแตกต่างของ cppreference:

แต่ไม่มีความแตกต่างระหว่าง C ++ 14 และ C ++ 17 ทำไมมันทำงานกับ C ++ 17 และไม่ได้กับ C ++ 14


คุณใช้คอมไพเลอร์ / ไลบรารีมาตรฐาน / แพลตฟอร์มใด
Victor Gubin

@VictorGubin ฉันลองกับ Clang และ GCC บน Linux (Wandbox) ฉันลองใช้เวอร์ชั่นอื่น
โทมัส Sablik

1
คุณสามารถทำให้ MCVE เป็นแบบโลคอลภายในmain(หรือฟังก์ชั่นใด ๆ โดยไม่จำเป็นต้องเป็นmain) แทนที่จะเป็นตัวสร้าง struct เสียงดังกราวให้เกิดข้อผิดพลาดที่คล้ายกันเป็นที่ชัดเจนมากขึ้นว่ามันพยายามที่จะใช้ที่ถูกลบสำเนาคอนสตรัคแทนการเริ่มต้นหรือคอนสตรัคธรรมดา: godbolt.org/z/SBGf9wกับ libc ++
ปีเตอร์ Cordes

@PeterCordes ฉันไม่แน่ใจว่าข้อผิดพลาดนี้เกี่ยวข้องกับการเริ่มต้นคลาสหรือไม่
โทมัส Sablik

3
การได้รับข้อความแสดงข้อผิดพลาดเดียวกันสำหรับตัวอย่างที่ทำซ้ำได้ง่ายน้อยที่สุดพิสูจน์ได้ว่าไม่ใช่ ฉันไม่แน่ใจจนกว่าจะลอง
Peter Cordes

คำตอบ:


29

เพราะใน C ++ 17 มีการรับประกัน RVO ในคำสั่ง C ++ 14 ที่ชอบFoo x = Foo(args)และFoo x (args)ไม่เหมือนกันทางเทคนิค แต่อยู่ใน 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(); 
}

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ที่นี่: https://en.cppreference.com/w/cpp/language/copy_elision

โดยเฉพาะอย่างยิ่งในส่วน(since C++17):

T x = T (T (f ())); // เพียงหนึ่งการเรียกไปยังตัวสร้างเริ่มต้นของ T เพื่อเริ่มต้น x

ในการทำให้รหัส C ++ 14 ทำงานคุณสามารถใช้

std::atomic_int idx { 1 };
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.