复制“struct atomic”的构造函数

时间:2014-10-14 19:43:30

标签: c++ templates c++11

我有以下代码:

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; }
....

我有几个问题:

  • b 编译正常。我在线 d 中理解构造函数被调用。正确?
  • a 无法编译。根据错误消息,调用行 c 中的复制构造函数,因此出现错误消息&#34;使用已删除的函数&#34; (据我所知)。

有人可以帮我理解Line 为什么/如何最终调用Line c (而不是Line d )。

2 个答案:

答案 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。