Boost logo

Boost :

From: Eric Niebler (eric.niebler_at_[hidden])
Date: 2006-11-21 13:09:49


John Maddock wrote:
> capourrait_at_[hidden] wrote:
>> Hi,
>>
>> It seem that there is a problem when using the substr function in
>> regex_match().
>
> Yes: substring() returns a *temporary* string object, by the time that
> regex_match returns the string it has searched has gone out of scope and
> been destroyed, so all the iterators stored in the match are now invalid.

<snip>

I recently discovered something new (to me) about rvalues and const
volatile references. It seems an rvalue will not bind to one. This
property can be used to prevent misuses such as the one above.

Consider the following:

#include <string>

template<typename T>
void foo( T const volatile & t)
{
}

std::string volatile bar()
{
     return std::string("");
}

int main()
{
     std::string str("");
     std::string const cstr("");
     foo(str); // works
     foo(cstr); // works
     //foo(str.substr(2)); // doesn't work
     //foo(bar()); // doesn't work
     return 0;
}

To solve John's problem, regex_match() can be defined to take a
"std::string const volatile &", and then it merely casts the volatile
away inside. (The foo(bar()) case serves to demonstrate that this trick
cannot be fooled by volatile-qualified rvalues, because std::string
doesn't have a volatile copy constructor -- and in practice, no types do.)

(Note: this doesn't work on any msvc compilers, which will happily bind
temporaries to const volatile references.)

It seems to me this property should also be usable to (finally!) solve
the problem of detecting the lvalue/rvalue-ness of an expression at
compile time, which would let us emulate decltype in C++03. But I have
yet to find a formulation that Comeau Online accepts. Perhaps I'll need
to refer to the standard.

--
Eric Niebler
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk