C ++ 14とC ++ 17ではstd :: atomicコンストラクターの動作が異なるのはなぜですか


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 ++ 14ではなくC ++ 17で動作するのはなぜですか?


どのコンパイラ/標準ライブラリ/プラットフォームを使用していますか?
Victor Gubin

@VictorGubin Linux(Wandbox)でClangとGCCを試してみました。別のバージョンを試しました。
Thomas Sablik

1
構造体コンストラクタの代わりに、MCVEを単純にローカルインmain(または関数である必要はないmain)に単純化できます。Clangが同様のエラーメッセージを表示し、イニシャライザまたはプレーンコンストラクタの代わりに削除されたコピーコンストラクタを使用しようとしていることをより明確にします:godbolt.org/z/SBGf9w with libc ++
Peter Cordes

@PeterCordesこのエラーがクラスの初期化に関連しているかどうかはわかりませんでした。
トーマスサブリック

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のデフォルトコンストラクターへの1回の呼び出しで、xを初期化します

C ++ 14コードを機能させるには、次を使用できます。

std::atomic_int idx { 1 };
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.