There is a class template Foo<T>. And for some specific type, a function should use lock_guard.
Here is the example code:
#include <type_traits>
#include <mutex>
#include <vector>
template<typename T>
class Foo {
public:
void do_something(int k) {
if constexpr(std::is_same_v<T, NeedMutexType>) {
std::lock_guard<std::mutex> lock(mtx_);
}
resource_.push_back(k);
// code for task with resource_ ...
}
private:
std::mutex mtx_;
std::vector<int> resource_;
};
The std::lock_guard will destructed in the end of if constexpr scope. (If it's not true, please correct me.)
To handle this, I can copy the code for task with resource_ below into the if constexpr scope, or just use the raw std::mutex such as mtx_.lock() & mtx_.unlock() instead.
Is there any some ways to handle this with std::lock_guard ? Thanks.
Perhaps std::conditional could come to the rescue here, if you need to do this kind of thing a lot.
Here we've defined a do-nothing class template that's constructed the same way as
std::lock_guard. We then use that withstd::conditionalto select eitherstd::lock_guardorFakeLockGuarddepending on the result of your type-check.Now you can use it as follows:
You can easily verify this works by setting a breakpoint in the
FakeLockGuardconstructor or making it output something.That's how you can make it all work at compile-time. But I think as you alluded to already, you can simply construct a
unique_lockand then conditionally lock it. This has the benefit of being much clearer to whoever has to work with your code. In the end, it's up to whatever you think is most appropriate.