Non Static Member Initialization and deleted copy constructor

This looks wrong to me. Is this a known bug?

#include <atomic>

//
// This class can compile
//
class Working
{
private:
    std::atomic<int> value_{0};
};

//
// This class cannot compile
//
template <typename Ty1>
class NotWorking
{
    private:
        std::atomic<int> value_{0}; // <---- error here
};

int main()
{
    Working working;
    NotWorking<int> not_working;
}

test.cpp:19:33: error: copying member subobject of type 'std::atomic<int>' invokes deleted constructor
        std::atomic<int> value_{0}; // <---- error here
                                ^
test.cpp:25:21: note: in instantiation of template class 'NotWorking<int>' requested here
    NotWorking<int> not_working;
                    ^
/Users/hhinnant/Development/temp_libcxx/include/atomic:721:7: note: copy constructor of 'atomic<int>' is implicitly deleted because base class
      '__atomic_base<int>' has a deleted copy constructor
    : public __atomic_base<_Tp>
      ^
/Users/hhinnant/Development/temp_libcxx/include/atomic:640:7: note: copy constructor of '__atomic_base<int, true>' is implicitly deleted because base class
      '__atomic_base<int, false>' has a deleted copy constructor
    : public __atomic_base<_Tp, false>
      ^
/Users/hhinnant/Development/temp_libcxx/include/atomic:625:5: note: function has been explicitly marked deleted here
    __atomic_base(const __atomic_base&) = delete;
    ^
1 error generated.

Thanks,
Howard

Ouch.

This isn’t restricted to non-static member initializers, it’s a problem with the way we instantiate direct-list-initialization in general:

#include
template struct X {
int f() {
std::atomic v{0};
return v;
}
};
int k = X().f();

:4:22: error: copying variable of type ‘std::atomic’ invokes deleted constructor
std::atomic v{0};
^ ~
:8:18: note: in instantiation of member function ‘X::f’ requested here
int k = X().f();
^
[…]

Actually, changing both initializations to assignments (“= 0”) generates the same error (“'std::atomic<int>' invokes deleted constructor”), but for both the class and the template class versions. Needless to say, simply default constructing works in both cases.

      Steve

Sure, but those cases are actually ill-formed. The problem is that the copy constructor is deleted, but direct initialization isn’t supposed to call the copy constructor.