In the code below, class B contains an array of member class class A.
B::A has one member bool and one member std::thread.
The code below compiles fine:
// main.cpp #include <mutex> #include <thread> class B { public: B(); private: class A { public: A( const bool& b ) : b_( b ) {} bool b_; std::thread thread_; } a_[2]; }; B::B() : a_{ { false }, { false } } { } int main( int argc, char* argv[] ) { B b; return 0; } $ g++ --version && g++ -g ./main.cpp g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 Copyright (C) 2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ Why does introducing a std::mutex to B::A introduce the following compile error?
// main.cpp #include <mutex> #include <thread> class B { public: B(); private: class A { public: A( const bool& b ) : b_( b ) {} bool b_; std::mutex mutex_; // I break compilation! std::thread thread_; } a_[2]; }; B::B() : a_{ { false }, { false } } { } int main( int argc, char* argv[] ) { B b; return 0; } $ g++ -g ./main.cpp ./main.cpp: In constructor 'B::B()': ./main.cpp:21:35: error: use of deleted function 'B::A::A(B::A&&)' B::B() : a_{ { false }, { false } } { } ^ ./main.cpp:11:9: note: 'B::A::A(B::A&&)' is implicitly deleted because the default definition would be ill-formed: class A { ^ ./main.cpp:11:9: error: use of deleted function 'std::mutex::mutex(const std::mutex&)' In file included from /usr/include/c++/6/mutex:44:0, from ./main.cpp:2: /usr/include/c++/6/bits/std_mutex.h:97:5: note: declared here mutex(const mutex&) = delete; ^~~~~ If I correctly understand the compile error, it's complaining that an instance of B::A cannot be created without explicit construction of B::A::mutex_. But if this is true, I don't understand why this should be necessary: std::mutex has a default constructor, so doesn't need any constructor arguments, as demonstrated below:
// main.cpp #include <mutex> int main( int argc, char* argv[] ) { std::mutex mutex[10]; return 0; } Please help me understand the nature of the above compile error, and what an appropriate fix might be.
Update: @Jarod42 and @chris seem to have discovered this is a compiler bug. I'm updating the question to ask if anyone could explain the nature of this bug -- initiaizing member array-of-object elements seems like such a simple and foundational thing. What type of objects trigger this bug and why? I can't imagine this could be a universal/easily reproducible problem...?
Update: A not-great workaround seems to be making B::A::A an empty constructor and initializing B::A::b_ with an rvalue. :(
// main.cpp #include <mutex> #include <thread> class B { public: B(); private: class A { public: A() : b_( false ) {} bool b_; std::mutex mutex_; std::thread thread_; } a_[2]; }; B::B() { } int main( int argc, char* argv[] ) { B b; return 0; } $ g++ -g ./main.cpp $ https://stackoverflow.com/questions/65947612/why-does-introducing-stdmutex-to-member-class-generate-this-compile-error January 29, 2021 at 09:33AM
没有评论:
发表评论