Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

implicit variable decleration:

55 views
Skip to first unread message

Doug Mika

unread,
Aug 1, 2015, 2:43:32 PM8/1/15
to
Quick question:

explicit variable decleration (I explicitly declare variable dummyLck):
unique_lock<std::mutex> dummyLck(dummyMtx); //of course this works

but I want to declare the dummyLck as an "implicit" variable without a name, and pass it directly to a condition variable, but the following line spits syntax errors...what's the syntax for doing this:
condition_variable threadsReady;
mutex dummyMtx;
threadsReady.wait(unique_lock<std::mutex>(dummyMtx)); //this syntax seems to be wrong, but why?

Bo Persson

unread,
Aug 1, 2015, 3:22:34 PM8/1/15
to
It's not the syntax, it's the semantics. The wait function takes a
non-const reference to a lock. That will not bind to a temporary.



Bo Persson

Alf P. Steinbach

unread,
Aug 1, 2015, 6:23:49 PM8/1/15
to
On 01-Aug-15 9:22 PM, Bo Persson wrote:
> On 2015-08-01 20:43, Doug Mika wrote:
[snipped]
>>
>> threadsReady.wait(unique_lock<std::mutex>(dummyMtx)); //this syntax
>> seems to be wrong, but why?
>>
>
> It's not the syntax, it's the semantics. The wait function takes a
> non-const reference to a lock. That will not bind to a temporary.

One way to obtain a reference to a temporary is

template< class Type >
auto temp_reference( Type&& o )
-> Type&
{ return o; }

The lifetime of the temporary extends to the end of the full-expression.

I vaguely remember that Dietmar Kuhl (I think it was, anyway I place the
blame for every ingenious insight on him) once showed a standard library
function that could do this. But I can't find it now. It's not `std::ref`.

I even more vaguely remember that there were some special related C++03
tricks for `std::string` and `std::ostringstream`, but for that, the
details elude me completely -- possibly something to do with `append`
for strings?


Cheers,

- Alf


--
Using Thunderbird as Usenet client, Eternal September as NNTP server.

Bo Persson

unread,
Aug 2, 2015, 4:43:44 AM8/2/15
to
Probably with streams, where you couldn't use tempories with the free
operator<<.

std::ostringstream() << x;

would fail, but

std::ostringstream().flush() << x;

would compile, as the flush member function would return an ostream&
that << x could use.


Has of course been fixed with an rvalue overload in later C++ versions.


Bo Persson

Doug Mika

unread,
Aug 3, 2015, 4:51:19 PM8/3/15
to
So the question that comes to me now is how did you know that the wait function takes a non-const reference to a lock? And how do you know that these don't allow rvalues?
I often use www.cplusplus.com as reference for all these little tidbits on various functions, and nowhere did I find what you wrote.

How can I deduce when I can use implicit variables as function parameters, and when I cannot?

Alf P. Steinbach

unread,
Aug 3, 2015, 5:09:25 PM8/3/15
to
On 03-Aug-15 10:51 PM, Doug Mika wrote:
>
> So the question that comes to me now is how did you know that the wait function
> takes a non-const reference to a lock?

Look at the documentation, e.g. <url:
http://en.cppreference.com/w/cpp/thread/condition_variable/wait>.

The formal argument type is reference to non-const, and only that.


> And how do you know that these don't allow rvalues?

The Holy Standard.

But any good introductory book should tell you that.


> I often use www.cplusplus.com as reference for all these little tidbits on
> various functions, and nowhere did I find what you wrote.

At the top of the page about that function, <url:
http://www.cplusplus.com/reference/condition_variable/condition_variable/wait/>.


> How can I deduce when I can use implicit variables as function parameters,
> and when I cannot?

Just check the documentation, or the source.

Besides, in general (not sure about Visual C++, but in general) the
compiler will tell you. ;-)


Cheers & hth.,

Öö Tiib

unread,
Aug 3, 2015, 5:11:12 PM8/3/15
to
On Monday, 3 August 2015 23:51:19 UTC+3, Doug Mika wrote:
> On Saturday, August 1, 2015 at 2:22:34 PM UTC-5, Bo Persson wrote:
> > On 2015-08-01 20:43, Doug Mika wrote:
> > > Quick question:
> > >
> > > explicit variable decleration (I explicitly declare variable dummyLck):
> > > unique_lock<std::mutex> dummyLck(dummyMtx); //of course this works
> > >
> > > but I want to declare the dummyLck as an "implicit" variable without a name, and pass it directly to a condition variable, but the following line spits syntax errors...what's the syntax for doing this:
> > > condition_variable threadsReady;
> > > mutex dummyMtx;
> > > threadsReady.wait(unique_lock<std::mutex>(dummyMtx)); //this syntax seems to be wrong, but why?
> > >
> >
> > It's not the syntax, it's the semantics. The wait function takes a
> > non-const reference to a lock. That will not bind to a temporary.
> >
> >
> >
> > Bo Persson
>
> So the question that comes to me now is how did you know that the
> wait function takes a non-const reference to a lock?

http://en.cppreference.com/w/cpp/thread/unique_lock/unique_lock
or
http://www.cplusplus.com/reference/mutex/unique_lock/unique_lock
both list:

explicit unique_lock( mutex_type& m );

That 'm' is clearly non-const lvalue reference.

> And how do you know that these don't allow rvalues?

Why there was added rvalue reference (&&)? It was added because the
lvalue reference (&) did not allow mutable lvalues.

> I often use www.cplusplus.com as reference for all these little tidbits
> on various functions, and nowhere did I find what you wrote.

How you look at it? Both common online references list the 'unique_lock'
as I did show above.

> How can I deduce when I can use implicit variables as function
> parameters, and when I cannot?

You can pass a temporary to by-value parameter, to rvalue reference
parameter and to reference to const parameter. You can not pass
temporary to reference to mutable parameter.

Öö Tiib

unread,
Aug 3, 2015, 5:14:38 PM8/3/15
to
On Tuesday, 4 August 2015 00:11:12 UTC+3, Öö Tiib wrote:
> Why there was added rvalue reference (&&)? It was added because the
> lvalue reference (&) did not allow mutable lvalues.

Meant mutable rvalues.

Alf P. Steinbach

unread,
Aug 3, 2015, 5:17:00 PM8/3/15
to
On 03-Aug-15 11:10 PM, Öö Tiib wrote:
> On Monday, 3 August 2015 23:51:19 UTC+3, Doug Mika wrote:
>>
>> So the question that comes to me now is how did you know that the
>> wait function takes a non-const reference to a lock?
>
> http://en.cppreference.com/w/cpp/thread/unique_lock/unique_lock
> or
> http://www.cplusplus.com/reference/mutex/unique_lock/unique_lock
> both list:
>
> explicit unique_lock( mutex_type& m );
>
> That 'm' is clearly non-const lvalue reference.
>

Uhm, that's not the `wait` function.

Cheers,

Öö Tiib

unread,
Aug 3, 2015, 5:34:04 PM8/3/15
to
On Tuesday, 4 August 2015 00:17:00 UTC+3, Alf P. Steinbach wrote:
> On 03-Aug-15 11:10 PM, Öö Tiib wrote:
> > On Monday, 3 August 2015 23:51:19 UTC+3, Doug Mika wrote:
> >>
> >> So the question that comes to me now is how did you know that the
> >> wait function takes a non-const reference to a lock?
> >
> > http://en.cppreference.com/w/cpp/thread/unique_lock/unique_lock
> > or
> > http://www.cplusplus.com/reference/mutex/unique_lock/unique_lock
> > both list:
> >
> > explicit unique_lock( mutex_type& m );
> >
> > That 'm' is clearly non-const lvalue reference.
> >
>
> Uhm, that's not the `wait` function.

Seems so ... perhaps I'm too tired today, thanks.

Bo Persson

unread,
Aug 3, 2015, 7:00:40 PM8/3/15
to
On 2015-08-03 22:51, Doug Mika wrote:
> On Saturday, August 1, 2015 at 2:22:34 PM UTC-5, Bo Persson wrote:
>> On 2015-08-01 20:43, Doug Mika wrote:
>>> Quick question:
>>>
>>> explicit variable decleration (I explicitly declare variable dummyLck):
>>> unique_lock<std::mutex> dummyLck(dummyMtx); //of course this works
>>>
>>> but I want to declare the dummyLck as an "implicit" variable without a name, and pass it directly to a condition variable, but the following line spits syntax errors...what's the syntax for doing this:
>>> condition_variable threadsReady;
>>> mutex dummyMtx;
>>> threadsReady.wait(unique_lock<std::mutex>(dummyMtx)); //this syntax seems to be wrong, but why?
>>>
>>
>> It's not the syntax, it's the semantics. The wait function takes a
>> non-const reference to a lock. That will not bind to a temporary.
>>
>>
>>
>> Bo Persson
>
> So the question that comes to me now is how did you know that the wait function takes a non-const reference to a lock?

I guessed that from your problem, and from knowing that a
condition_variable must do something to the mutex. Like unlock it while
waiting.

Then I checked the reference. :-)


> And how do you know that these don't allow rvalues?

I'm an old guy, and remember reading that Bjarne initially allowed
references to tempories but found that it caused too many bugs. Updates
to temporaries were "mysteriously" lost.

For example:

void f(long& x)
{ ++x; }

int y = 0;
f(y); // not allowed

If this was allowed, the int would be converted to a temporary long, and
the long would incremented, not the int.

By limiting temporaries to const references, they cannot be changed (as
they are const) and this kind of bugs goes away.



> I often use www.cplusplus.com as reference for all these little tidbits on various functions, and nowhere did I find what you wrote.
>

Unfortunately, the C++ standard has to be read holistically. It often
says "unless otherwise specified", and then you have to read everything
else to see if it IS specified differently 200 pages further on.

> How can I deduce when I can use implicit variables as function parameters, and when I cannot?
>

If they are passed by value, or by const reference, or by rvalue
reference... Just not by non-const lvalue reference. :-)


Bo Persson

Doug Mika

unread,
Aug 4, 2015, 3:19:43 PM8/4/15
to
that cleared it up...thanks to all
0 new messages