Std :: atom yapıcı neden C ++ 14 ve C ++ 17'de farklı davranıyor?


19

C ++ 11 ile bir projede çalışıyorum ve aşağıdaki kodu denedim

#include <atomic>

struct A {
    std::atomic_int idx = 1;

};

int main() {
    return 0;
}

Derleyici hatası alıyorum

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

Aynı sonuç C ++ 14 ile aynıdır. C ++ 17'ye geçiş yaptığımda çalışır: wandbox

Cppreference'yi farklılıklar açısından kontrol ettim:

Ancak C ++ 14 ve C ++ 17 arasında belgelenmiş bir fark yoktur. Neden C ++ 14 ile değil C ++ 17 ile çalışıyor?


Hangi derleyici / standart kütüphane / platformu kullanıyorsunuz?
Victor Gubin

@VictorGubin Linux'ta Clang ve GCC ile denedim (Wandbox). Farklı versiyonları denedim.
Thomas Sablik

1
MCVE'yi bir yapıcı yerine yalnızca yerel bir main(veya herhangi bir işlev, olması gerekmez main) ile basitleştirebilirsiniz . Clang benzer bir hata mesajı veriyor , başlatıcı veya düz kurucu yerine silinmiş bir kopya kurucu kullanmaya çalışıyor : libbol ++ ile godbolt.org/z/SBGf9w
Peter Cordes

@PeterCordes Bu hatanın sınıf başlatma ile ilgili olup olmadığından emin değildim.
Thomas Sablik

3
Daha basit bir minimum tekrarlanabilir örnek için aynı hata mesajını almak bunun olmadığını kanıtlar. Denemeden de emin değildim.
Peter Cordes

Yanıtlar:


29

Çünkü C ++ 17'de garantili bir RVO vardır. C ++ 14 ifadeleri gibi Foo x = Foo(args)ve Foo x (args)teknik olarak aynı değildir, ancak C ++ 17'de bulunmaktadır.

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(); 
}

Bununla ilgili daha fazla bilgiyi buradan edinebilirsiniz: https://en.cppreference.com/w/cpp/language/copy_elision

Özellikle bölüm (since C++17):

T x = T (T (f ())); // x'i başlatmak için T'nin varsayılan yapıcısına yalnızca bir çağrı

C ++ 14 kodunu çalıştırmak için aşağıdakileri kullanabilirsiniz:

std::atomic_int idx { 1 };
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.