Document number: P0739R0
Date: 2017-07-13
Reply-To:
Mike Spertus, Symantec (mike_spertus@symantec.com)
Walter E. Brown ( webrown.cpp@gmail.com)
Stephan T. Lavavej (stl@exchange.microsoft.com)
Audience: {Library Evolution, Library} Working Group
mutex m;
scoped_lock l(m, adopt_lock);
The point here is that when the compiler attempts to deduce scoped_lock<m1, adopt_lock>, there is a
hard error outside the immediate context as adopt_lock is not lockable. Note that the same
code works fine if scoped_lock is replaced by lock_guard because lock_guard
does not have a variadic argument. We recommend fixing this by moving the adopt_lock_t parameter to the front of the parameter list. This was not done originally because scoped_lock was originally named lock_guard and had to remain compatible to avoid code breakage, which is no longer a requirement now that scoped_lock is a different class than lock_guard. This is useful to fix because it will encourage programmers to migrate to consistent use of scoped_lock rather than choosing one or the other based on circumstances.
Likewise, change §33.4.4.2 [thread.lock.scoped] starting immediately before paragraph 4 as follows:explicit scoped_lock(MutexTypes&... m); explicit scoped_lock(MutexTypes&... m, adopt_lock_t); explicit scoped_lock(adopt_lock_t, MutexTypes&... m); ~scoped_lock();
explicit scoped_lock(MutexTypes&... m, adopt_lock_t); explicit scoped_lock(adopt_lock_t, MutexTypes&... m);Requires: The calling thread owns all the mutexes in m.
variant<int, double> v1(3);
variant v2 = v1; // Ill-formed!
As this natural code is useful and its failure is confusing, we propose that it be supported.
Indeed, prior to the adoption of p0510r0 banning variant<>,
the above code worked as expected since variant<> occurs in some deduction
guides in the overload set. As it is not clear that constructor template argument deduction
was considered in adopting p0510r0, we would like to consider allowing variant<>
not to produce a hard error in such cases.
Remarks: This function shall not participate in overload resolution unless sizeof...(Types) is nonzero, unless is_same_v<decay_t<T>, variant> is false, unless decay_t<T> is neither a specialization of in_place_type_t nor a specialization of in_place_index_t, unless is_constructible_v<Tj, T> is true, and unless the expression FUN(std::forward<T>(t)) (with FUN being the above-mentioned set of imaginary functions) is well formed.