boost::range vs && (rvalue ref)
Passing range by ref (&) is fine, but using (&&) results in and error. Any ideas? #include <boost/range.hpp> #include <vector> template<typename out_t> void F (out_t && o) { typedef typename boost::range_value<out_t>::type T; } void G() { std::vector<int> v; F (v); } usr/local/src/boost_1_52_0/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<false, boost::range_const_iterator<std::vector<int>&>, boost::range_mutable_iterator<std::vector<int>&> >::f_ {aka struct boost::range_mutable_iterator<std::vector<int>&>}’ bug.cc: In instantiation of ‘void F(out_t&&) [with out_t = std::vector<int>&]’: bug.cc:12:7: required from here bug.cc:6:52: error: no type named ‘type’ in ‘struct boost::range_value<std::vector<int>&>’
Passing range by ref (&) is fine, but using (&&) results in and error. Any ideas?
[snip]
When you pass by T&&, the deduced type of T will include the reference. (So e.g. if you have a T&& argument and you pass in an int rvalue, T will be deduced as 'const int&'. If you pass an int lvalue, T will be deduced as 'int&'. This is in contrast to a regular reference, like T&, where if you pass an int lvalue, T will be deduced as just 'int'). Range metafunctions don't accept references to range types as their input; you must pass the range type itself. So, you must call remove_reference<> on the deduced type 'T' prior to passing it to a range metafunction. I wonder if we should change the range metafunctions to accept references to range types, and do the reference stripping themselves? Regards, Nate
On 11-01-2013 04:37, Nathan Ridge wrote:
Passing range by ref (&) is fine, but using (&&) results in and error. Any ideas?
[snip]
When you pass by T&&, the deduced type of T will include the reference. (So e.g. if you have a T&& argument and you pass in an int rvalue, T will be deduced as 'const int&'. If you pass an int lvalue, T will be deduced as 'int&'. This is in contrast to a regular reference, like T&, where if you pass an int lvalue, T will be deduced as just 'int').
Range metafunctions don't accept references to range types as their input; you must pass the range type itself.
So, you must call remove_reference<> on the deduced type 'T' prior to passing it to a range metafunction.
I wonder if we should change the range metafunctions to accept references to range types, and do the reference stripping themselves?
I think we should. This has come up before. -Thorsten
Thorsten Ottosen wrote:
On 11-01-2013 04:37, Nathan Ridge wrote:
Passing range by ref (&) is fine, but using (&&) results in and error. Any ideas?
[snip]
When you pass by T&&, the deduced type of T will include the reference. (So e.g. if you have a T&& argument and you pass in an int rvalue, T will be deduced as 'const int&'. If you pass an int lvalue, T will be deduced as 'int&'. This is in contrast to a regular reference, like T&, where if you pass an int lvalue, T will be deduced as just 'int').
Range metafunctions don't accept references to range types as their input; you must pass the range type itself.
So, you must call remove_reference<> on the deduced type 'T' prior to passing it to a range metafunction.
I wonder if we should change the range metafunctions to accept references to range types, and do the reference stripping themselves?
I think we should. This has come up before.
-Thorsten
My objective is to support this common type of usage: template<typename out_t> F (out_t & o) { } F (boost::make_iterator_range (blah.begin(), blah.end()));
Thorsten Ottosen wrote:
On 1--1--013 4::7,, Nathan Ridge wrote:
Passing range by ref (&) is fine, but using (&&) results in and error. Any ideas?
[snip]
[snip]
Range metafunctions don't accept references to range types as their input; you must pass the range type itself.
So, you must call remove_reference<> on the deduced type 'T' prior to passing it to a range metafunction.
I wonder if we should change the range metafunctions to accept references to range types, and do the reference stripping themselves?
I think we should. This has come up before.
-Thorsten
My objective is to support this common type of usage:
template<typename out_t> F (out_t & o) { }
F (boost::make_iterator_range (blah.begin(), blah.end()));
I filed https://svn.boost.org/trac/boost/ticket/885 . In the meantime, you can use the remove_reference workaround I mentioned, as follows: template<typename out_t> void F (out_t && o) { typedef typename boost::range_value<typename boost::remove_reference<out_t>::type>::type T; } Regards, Nate
participants (3)
-
Nathan Ridge
-
Neal Becker
-
Thorsten Ottosen