By design, class B
is uncopiable but movable.
Recently, I enjoy that B
has automatically-generated move constructor and move assignment operator.
Now, I add std::mutex
to class B
.
The problem is that std::mutex
can't be moved.
#include <iostream>
#include <string>
#include <vector>
#include <mutex>
class C{
public: C(){}
public: C(C&& c2){ }
public: C& operator=(C&& c2){ return *this; }
//: by design, I don't allow copy, can only move
};
class B{public: int a=0;
C c;
//------ 10+ trivial fields ---
//private: std::mutex mutexx; //<=== uncomment = uncompilable
};
int main(){
B b1;
B b2;
b1=std::move(b2);
}
Is there a solution to make it compile?
My poor workaround 1 (manual)
Manually create 2 move functions.
class B{public: int a=0;
C c;
//------ 10+ trivial fields ---
private: std::mutex mutexx;
public: B(B&& b2){
this->c=std::move(b2.c);
//--- copy other trivial fields (long and hard to maintain) --
//:: intentionally omit move/copy of mutex
}
public: B& operator=(B&& b2){ ... }
};
This workaround creates the effect that I want.
My poor workaround 2 (unique_ptr)
Use std::unique_ptr<std::mutex>
, but there are 3 minor disadvantages :-
- Very ugly
- Add a bit of extra heap & cpu cost. The cost might be little, but I will resent it forever.
- I also need to refactor some of my code from
mutexx.lock()
tomutexx->lock()
Edit : My poor workaround 3 (encapsulate mutex)
(Add after get the first answer)
Encapsulate std::mutex
into a new class, and create 2 move functions that do nothing.
If future reader may use this approach, beware that my question itself is questionable.
Thank "ALX23z" and "j6t" for warning.