我有以下代码:
enum class State : uint32_t
{
FREE,
IDLE,
COAST,
MOVE,
STOP
};
std::atomic<State> car1_state = State::IDLE; <--- Line a
std::atomic<State> car2_state(State::IDLE); <--- Line b
以下是来自原子头文件的片段:
// c++ header file - atomic
template<typename _Tp>
struct atomic
{
private:
_Tp _M_i;
public:
atomic() noexcept = default;
~atomic() noexcept = default;
atomic(const atomic&) = delete; <--- Line c
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } <--- Line d
operator _Tp() const noexcept
{ return load(); }
operator _Tp() const volatile noexcept
{ return load(); }
_Tp
operator=(_Tp __i) noexcept
{ store(__i); return __i; }
....
我有几个问题:
有人可以帮我理解Line 为什么/如何最终调用Line c (而不是Line d )。
答案 0 :(得分:5)
复制初始化需要可访问的非显式复制或移动构造函数,因为它正式初始化来自相同类型的临时prvalue的变量。也就是说,
Foo a = x;
相当于:
Foo a = Foo(x);
您的类型没有可访问的复制构造函数,因此出错。相比之下,直接初始化不需要复制构造函数:
Foo a(x);
答案 1 :(得分:2)
这是直接初始化和复制初始化之间的区别。让我们概括一下:
A a1 = b;
A a2(b);
如果b
的类型为A
,则两行相同。他们都会调用A
的复制构造函数。
但是,如果b
的类型与A
不同,则它们的语义也不同。 a2
由直接初始化初始化,调用A
的{{1}}类型的相应构造函数。
b
由复制初始化初始化,其作用是“从参数初始化一个临时对象,然后使用复制构造函数将该临时复制到最后一个对象。“因此在这种情况下,复制初始化等同于:
a1
在您的情况下,这会失败,因为复制构造函数被删除,并且没有移动构造函数。
要完全回答你的第二个问题,它不会调用Line c 而不是行 d,,但除了之外行 d。