聚合初始化原子成员
Initialize atomic members in aggregate
似乎无法使用 C++14 初始化聚合中的原子成员。以下不起作用 (live on gcc 8.0.1):
#include <atomic>
#include <iostream>
struct stru {
std::atomic_int32_t val_0;
std::atomic_int32_t val_1;
};
int main() {
auto p = new stru{0, 1};
std::cout << p->val_0 << ", " << p->val_1 << std::endl;
}
错误信息:
error: use of deleted function 'std::atomic<int>::atomic(const std::atomic<int>&)'
auto p = new stru{0, 1};
^
这是因为原子类型既不可复制也不可移动,因此不可复制初始化。然而,以下似乎有效(live on gcc 8.0.1)。
#include <atomic>
#include <iostream>
struct stru {
std::atomic_int32_t val_0;
std::atomic_int32_t val_1;
};
int main() {
auto p = new stru{};
std::cout << p->val_0 << ", " << p->val_1 << std::endl;
}
这有效地执行了零初始化,因此无法初始化为零以外的值。有没有办法初始化为其他指定值?
1
和 0
不是 std::atomic_int32_t
。以下作品:
#include <atomic>
#include <iostream>
struct stru {
std::atomic_int32_t val_0;
std::atomic_int32_t val_1;
};
int main() {
auto p = new stru{{0}, {1}};
std::cout << p->val_0 << ", " << p->val_1 << std::endl;
}
编辑:为什么会这样? Copy initialization kicks in 对于初始化列表中的每个元素:
Each direct public...non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.
在您的示例中,1
和 0
被隐式转换为 std::atomic_int32_t
,并且 std::atomic_int32_t
不能从 [=] 变为 copy-initialized 13=]。在额外的 {}
版本中,val_0
和 val_1
是从 std::initializer_list<int>
复制初始化的,这很好。
Patrick 的 works, but his explanation doesn't look right to me. So I post the explanation I find here. For the code auto p = new stru{{0}, {1}};
aggregate initialization 效果:
If the initializer clause is a nested braced-init-list (which is not
an expression), the corresponding array element/class member/public
base (since C++17) is list-initialized from that clause: aggregate
initialization is recursive.
因此,成员不是复制初始化,而是从 braced-init-list 复制 list-initialized。
似乎无法使用 C++14 初始化聚合中的原子成员。以下不起作用 (live on gcc 8.0.1):
#include <atomic>
#include <iostream>
struct stru {
std::atomic_int32_t val_0;
std::atomic_int32_t val_1;
};
int main() {
auto p = new stru{0, 1};
std::cout << p->val_0 << ", " << p->val_1 << std::endl;
}
错误信息:
error: use of deleted function 'std::atomic<int>::atomic(const std::atomic<int>&)'
auto p = new stru{0, 1};
^
这是因为原子类型既不可复制也不可移动,因此不可复制初始化。然而,以下似乎有效(live on gcc 8.0.1)。
#include <atomic>
#include <iostream>
struct stru {
std::atomic_int32_t val_0;
std::atomic_int32_t val_1;
};
int main() {
auto p = new stru{};
std::cout << p->val_0 << ", " << p->val_1 << std::endl;
}
这有效地执行了零初始化,因此无法初始化为零以外的值。有没有办法初始化为其他指定值?
1
和 0
不是 std::atomic_int32_t
。以下作品:
#include <atomic>
#include <iostream>
struct stru {
std::atomic_int32_t val_0;
std::atomic_int32_t val_1;
};
int main() {
auto p = new stru{{0}, {1}};
std::cout << p->val_0 << ", " << p->val_1 << std::endl;
}
编辑:为什么会这样? Copy initialization kicks in 对于初始化列表中的每个元素:
Each direct public...non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.
在您的示例中,1
和 0
被隐式转换为 std::atomic_int32_t
,并且 std::atomic_int32_t
不能从 [=] 变为 copy-initialized 13=]。在额外的 {}
版本中,val_0
和 val_1
是从 std::initializer_list<int>
复制初始化的,这很好。
Patrick 的 auto p = new stru{{0}, {1}};
aggregate initialization 效果:
If the initializer clause is a nested braced-init-list (which is not an expression), the corresponding array element/class member/public base (since C++17) is list-initialized from that clause: aggregate initialization is recursive.
因此,成员不是复制初始化,而是从 braced-init-list 复制 list-initialized。