为什么std :: atomic构造函数在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一起使用?


您使用什么编译器/标准库/平台?
维克多·古宾

@VictorGubin我在Linux(Wandbox)上尝试了Clang和GCC。我尝试了不同的版本。
Thomas Sablik

1
您可以将MCVE简化为仅本地main变量(或任何函数,不需要main),而不是struct构造函数。Clang给出了类似的错误消息,更明确地表明它正在尝试使用已删除的副本构造函数而不是初始化构造函数或普通构造函数:godbolt.org/z/SBGf9w with libc ++
Peter Cordes

@PeterCordes我不确定此错误是否与类初始化有关。
Thomas Sablik

3
对于更简单的最小可重现示例,获得相同的错误消息证明事实并非如此。在尝试之前,我也不确定。
彼得·科德斯

Answers:


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 };
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.