我正在尝试创建和初始化一个包含非平凡类的成员数组的类,该数组包含一些状态和(在某些角落)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
,我可以使用标准构造函数初始化程序或使用新的声明内初始化正确初始化它,没有任何问题。无论我尝试什么,对成员数组执行相同操作都会失败并出现上述错误。
我真的不介意数组元素显然是作为临时构造的,然后移动而不是直接构造,但它不编译的事实显然有点令人讨厌。
有没有办法强制编译器构造(而不是移动)数组元素,或者我可以解决这个问题?