自明ではないクラスのメンバー配列を含むクラスを作成して初期化しようとしています。これには、いくつかの状態と (いくつかのコーナーの周り) が含まれていますstd::atomic_flag
。C++11 以降では、メンバー配列を初期化できるはずです。
コードは (最小限に) 次のようになります。
class spinlock
{
std::atomic_flag flag;
bool try_lock() { return !flag.test_and_set(std::memory_order_acquire); }
public:
spinlock() : flag(ATOMIC_FLAG_INIT){};
void lock() { while(!try_lock()) ; }
void unlock() { flag.clear(std::memory_order_release); }
};
class foo
{
spinlock lock;
unsigned int state;
public:
foo(unsigned int in) : state(in) {}
};
class bar
{
foo x[4] = {1,2,3,4}; // want each foo to have different state
public:
//...
};
コンパイラの出力を正しく理解している場合、これはメンバー配列を構築するのではなく、一時を構築し、移動/コピー コンストラクターを呼び出して、サブクラスで移動コンストラクターを呼び出しますstd::atomic_flag
。私が得たコンパイラ出力(gcc 4.8.1)は次のとおりです。
[...] error: use of deleted function 'foo::foo(foo&&)'
note: 'foo::foo(foo&&)' is implicitly deleted because the default definition would be ill-formed
error: use of deleted function 'spinlock::spinlock(spinlock&&)'
note: 'spinlock::spinlock(spinlock&&)' is implicitly deleted because [...]
error: use of deleted function 'std::atomic_flag::atomic_flag(const std::atomic_flag&)'
In file included from [...]/i686-w64-mingw32/4.8.1/include/c++/atomic:41:0
[etc]
配列を削除し、代わりに単一のfoo
メンバーを内部bar
に配置すると、標準のコンストラクター初期化子を使用するか、新しい宣言内初期化を使用して適切に初期化できますが、まったく問題ありません。メンバー配列で同じことを行うと、何を試しても上記のエラーで失敗します。
配列要素が明らかに一時的に構築され、直接構築されるのではなく移動されることはあまり気にしませんが、コンパイルされないという事実は明らかにショーストッパーです。
配列要素を強制的に構築する (移動しない) ようにする方法、またはこれを回避する方法はありますか?