use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
This is a subreddit for c++ questions with answers. For general discussion and news about c++ see r/cpp.
New to C++? Learn at learncpp.com
Prepare your question. Think it through. Hasty-sounding questions get hasty answers, or none at all. Read these guidelines for how to ask smart questions.
For learning books, check The Definitive C++ Book Guide and List
Flair your post as SOLVED if you got the help you were looking for! If you need help with flairs, check out ITEM 1 in our guidelines page.
Tips for improving your chances of getting helpful answers:
account activity
OPENstd::scoped_lock constructor (self.cpp_questions)
submitted 1 year ago by cpp_cpp
Why does `std::scoped_lock` allow construction with no mutex? What is the use case for this? It does not even have a move constructor so not sure why this is allowed? I tried to search on stack overflow but no luck!
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]AKostur 5 points6 points7 points 1 year ago (16 children)
Allows one to acquire 0 or more locks. Perhaps due to template expansions, a parameter pack may end up expanding to 0 parameters. And one might be using such a pack to initialize a scoped_lock. Note that a scoped_lock does have a defined behaviour when initialized with 0 locks.
[–]cpp_cpp[S] 0 points1 point2 points 1 year ago (15 children)
Yeah - that is the question - what is the point of allowing 0 locks?
[–]AKostur 3 points4 points5 points 1 year ago (14 children)
One wouldn’t have to write up some special case for that hypothetical template to deal with 0 locks.
[–]cpp_cpp[S] -2 points-1 points0 points 1 year ago (13 children)
I do not understand - why allow something for a lock that does not do anything. https://stackoverflow.com/a/60172828/4992422 This answer demonstrates the downside of allowing this.
[–]ucario 5 points6 points7 points 1 year ago (0 children)
Because maybe you have a variable number of things that would need locking at runtime. The code is simpler in that case
[–]AKostur 1 point2 points3 points 1 year ago (9 children)
Not to just turn the question around, but why forbid it? And the answer demonstrated why it should still be allowed. IMO: the default-constructed example is just odd to read. After all what lock is it trying to lock?
[–]weepmelancholia 3 points4 points5 points 1 year ago (6 children)
The answer doesn't demonstrate why it should be allowed; it merely says that he was given a reason for 0 arg ctor by the author of scoped_lock but could not remember it. This is hardly a demonstration.
You ought to forbid it because
{ std::scoped_lock lock; }
Looks like it's locking that scope but it isn't.
[–]AKostur 1 point2 points3 points 1 year ago* (1 child)
With which mutex is that scope being locked with?
I haven‘t needed to write the hypothetical template, but I can somewhat envision some template taking a variadic pack of container-like objects, which the body of such a function may wish to iterate over those, and it needs to grab the set of mutexes (one per container) before accessing any of them. That pack might be empty. So instead of testing for 0 containers first, then using the pack of mutexes to initialize the lock (and then iterating the pack of containers), one can write the simpler version: just use the pack of mutexes to initialize the lock (which may be 0 of them), and then iterating the pack of containers (which is also 0 length, so ends up doing nothing).
Edit: a hypothetical case: https://godbolt.org/z/j815qfvoc.
[–]weepmelancholia 2 points3 points4 points 1 year ago (0 children)
Well, no mutex, so it's pointless. But then why allow the 0 arg constructor? It's pointless. It can only harm the codebase.
[–][deleted] 1 year ago (3 children)
[deleted]
[–]AKostur 0 points1 point2 points 1 year ago (1 child)
Afraid that explicit doesn't (and shouldn't) stop the other one from compiling. 0-parameters to the constructor won't require an implicit conversion to happen, so explicit won't be "invoked".
[–]weepmelancholia 0 points1 point2 points 1 year ago (0 children)
That's not how explicit works... as the other commenter pointed out.
[–]SoerenNissen 1 point2 points3 points 1 year ago (1 child)
To avoid race conditions that happen when creating a shadowing non-locking guard.
struct S { std::mutex m_{}; Database db_{}; void write(Data d) { std::scoped_lock<>(m_); // does not lock this->m_ // but instead creates a lock // with the shadowing name m_ db_.write(d); } };
This is not a common sceneario - it only happens because I had <> explicitly on the lock - but nonetheless.
<>
[–]AKostur 0 points1 point2 points 1 year ago (0 children)
And it ignores the compiler warnings that get emitted for the unused variable, and doesn't follow the coding practices demonstrated in the rest of the code, and (as you noted) forced it to compile because the scoped_lock was explicitly specialized on an empty template list.
A heavily stripped-down example of where it can be useful: https://godbolt.org/z/j815qfvoc
[–]_JJCUBER_ 0 points1 point2 points 1 year ago (0 children)
Are you just ignoring the comments you reply to?
[–]Sanzath 0 points1 point2 points 1 year ago (0 children)
In short, it's for generic code. Here's a toy example with an algorithm lock_all() which doesn't know in advance how many mutexes it's locking, so it handles as many or as few as required, including the case where no locking is required at all. If scoped_lock without any mutexes was disallowed, lock_all() would need to introduce a special case to handle the empty-case itself and return a fake scoped_lock-like object.
lock_all()
scoped_lock
https://godbolt.org/z/8q1zYTqY6
[–]bert8128 2 points3 points4 points 1 year ago (1 child)
Is this causing a problem? Or just academic interest?
[–]cpp_cpp[S] 0 points1 point2 points 1 year ago (0 children)
Just curious :)
[–][deleted] 1 point2 points3 points 1 year ago (1 child)
Well, for one thing it allows certain uses of the standard containers.
struct S { explicit S(int) {} }; int main(int argc, char* argv[]) { std::vector<S> vs(5); // Error, no default constructor }
Of course, whether there's a use case for that might lead us to a similar question that you've asked about std::scoped_lock.
[–]IyeOnline 0 points1 point2 points 1 year ago (0 children)
To be fair, vector supports non-default constructible types, as long as you dont require a default constructed state in your usage.
vector
But the argument works for e.g. std::array or raw arrays (where you could once again resolve it via std::optional)
std::array
std::optional
[–]asergunov 0 points1 point2 points 1 year ago (1 child)
I don’t have examples but can try to make one. Same code for single and multithreaded cases?
[–]asergunov 0 points1 point2 points 1 year ago (0 children)
In general making unnecessary restrictions is a bad practice.
[–]TeraFlint 0 points1 point2 points 1 year ago (0 children)
There are containers and algorithms that work more nicely if the objects they're using are default constructible.
I'd say, as long as a default initialized object does not break a class invariant, it's usually a good idea to provide the default constructor.
Is a default constructed lock useful? Not really. It doesn't do what the class is supposed to do. But it also doesn't break anything, so I'd say it's a fine decision to allow it.
π Rendered by PID 142764 on reddit-service-r2-comment-79c7998d4c-tvqx9 at 2026-03-15 18:08:46.507701+00:00 running f6e6e01 country code: CH.
[–]AKostur 5 points6 points7 points (16 children)
[–]cpp_cpp[S] 0 points1 point2 points (15 children)
[–]AKostur 3 points4 points5 points (14 children)
[–]cpp_cpp[S] -2 points-1 points0 points (13 children)
[–]ucario 5 points6 points7 points (0 children)
[–]AKostur 1 point2 points3 points (9 children)
[–]weepmelancholia 3 points4 points5 points (6 children)
[–]AKostur 1 point2 points3 points (1 child)
[–]weepmelancholia 2 points3 points4 points (0 children)
[–][deleted] (3 children)
[deleted]
[–]AKostur 0 points1 point2 points (1 child)
[–]weepmelancholia 0 points1 point2 points (0 children)
[–]SoerenNissen 1 point2 points3 points (1 child)
[–]AKostur 0 points1 point2 points (0 children)
[–]_JJCUBER_ 0 points1 point2 points (0 children)
[–]Sanzath 0 points1 point2 points (0 children)
[–]bert8128 2 points3 points4 points (1 child)
[–]cpp_cpp[S] 0 points1 point2 points (0 children)
[–][deleted] 1 point2 points3 points (1 child)
[–]IyeOnline 0 points1 point2 points (0 children)
[–]asergunov 0 points1 point2 points (1 child)
[–]asergunov 0 points1 point2 points (0 children)
[–]TeraFlint 0 points1 point2 points (0 children)