Copy constructor "struct atomic"

I have the following code:

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

      

Below is a snippet from an atom header file:

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

      

I have several questions:

  • Line b compiles fine. My comprehension constructor is called on line d. Right?
  • Failed compilation line. For the error message, the copy constructor on line c is called, which is why the error message "using remote function" appears (which I understand).

Can someone please help me understand why / how Line a ends up calling Line c (and not Line d).

+3


source to share


2 answers


An accessible, implicit instance or move mechanism is required to initialize a copy, since it formally initializes a variable from a temporary assignment of the same type. I.e

Foo a = x;

      

equivalent to:



Foo a = Foo(x);

      

Your type does not have a copy constructor available, hence the error. In contrast, direct initialization does not require a copy constructor:

Foo a(x);

      

+5


source


This is the difference between direct initialization and copy initialization. Let's summarize it:

A a1 = b;
A a2(b);

      

If type b

is equal A

, the two strings are identical. They will both call the copy constructor A

.

However, if the type b

is different from A

, their semantics are also different. a2

initialized by direct initialization, which calls the appropriate A

type constructor b

.



a1

, on the other hand, is initialized with copy initialization, which works like "initializes a temporary object from an argument, and then uses a copy constructor to copy that temporary object to the target object." So in this case, copy initialization is equivalent to this:

A a1(A(b));

      

In your case, this fails because the copy constructor has been removed and there is no move constructor.

And to fully answer your second question, it doesn't call Line c instead of Line d, but in addition to Line d.

+2


source







All Articles