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).
source to share
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);
source to share
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.
source to share