Re: How to detect const reference to temporary issues at compile or runtime?
Am 02.12.2010 19:35, schrieb SG:
On 2 Dez., 13:11, Daniel Kr?gler wrote:
In fact the new C++0x library follows a similar approach in regard to
the class template reference_wrapper (which is quite similar to class Y
above):
template<class T> reference_wrapper<T> ref(T&);
template<class T> reference_wrapper<const T> cref(const T&);
template<class T> void ref(const T&&) = delete;
template<class T> void cref(const T&&) = delete;
template<class T> reference_wrapper<T> ref(reference_wrapper<T>);
template<class T> reference_wrapper<const T> cref(reference_wrapper<T>);
and the class template synopsis:
template<class T> class reference_wrapper
[..]
{
public :
[..]
// construct/copy/destroy
reference_wrapper(T&);
reference_wrapper(T&&) = delete; // do not bind to temporary objects
reference_wrapper(const reference_wrapper<T>& x);
[..]
};
Hmm... Is an implicit constructor a good idea here? I think we could
make reference_wrapper safer to use if the constructor was explicit.
Then, initializing such a reference_wrapper via copy initialization
forces us to use std::ref or std::cref respectivly -- which would be
nice, I guess. I find such classes with implicit constructors that
store the address of an argument somewhat disturbing.
The explicit has intentionally been removed as part of solving
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#689
At that time no real argument had been brought forward that would speak against
this implicit conversion.
An example where an implicit conversion is useful is the simple creation
of views, e.g.:
#include <functional>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
int main()
{
int a[] = { 5, 1, 8, 4 };
std::vector<std::reference_wrapper<int>> v(a, a + 4);
std::sort(v.begin(), v.end());
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(
std::cout, " "));
std::cout << std::endl;
std::copy(a, a + 4, std::ostream_iterator<int>( std::cout, " "));
std::cout << std::endl;
}
Note that the sequence requirements (N3126 23.2.3/3) impose that the input
iterator range shall refer to elements implicitly convertible to value_type.
Only with the non-explicit constructor, the assertion
static_assert(std::is_convertible<int&, std::reference_wrapper<int>>::value,
"Shall be implicit convertible");
holds (Several current library implementations ignore that constraint, because
it is imposed on the user, not on the library).
Or do we rely on this implicit "conversion" somewhere in the new
standard library?
AFAIK the library does not depend on this convertibility.
HTH & Greetings from Bremen,
- Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]