|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2005-05-11 16:50:04
Thorsten Ottosen wrote:
> "Peter Dimov" <pdimov_at_[hidden]> wrote in message
> news:004101c5566a$6aaecd50$6401a8c0_at_pdimov2...
>> Thorsten Ottosen wrote:
>>
>>> I don't know why you insists that we need two overloads.
>>>
>>> Given
>>>
>>> template< class T >
>>> MyType
>>> {
>>> Iter Begin();
>>> ConstIter Begin() const;
>>> ...
>>> };
>>>
>>> surely
>>>
>>> template< class T >
>>> auto begin( MyType<T>&& r ) -> decltype( r.Begin() )
>>> { return r.Begin(); }
>>>
>>> can handle both const and non-const arguments.
>>
>> No, it can't.
>
> do you care to explain why...I thought this was how we were supposed
> to solve the forwarding problem.
A forwarding function has a signature of the form
template<class T> auto begin( T && t );
When begin() is called on a const object, template argument deduction
deduces T as a const type.
X const x;
begin( x ); // T == X const &, T && == X const &
X const f();
begin( f() ); // T == X const, T && == X const &&
However, when you use MyType<T> &&:
template<class T> auto begin( MyType<T> && t );
MyType<int> const x;
begin( x ); // T == int
template argument deduction deduces T as int, and the attempt to bind
MyType<int>&& to x fails. An rvalue reference respects cv qualifiers, just
like an lvalue reference does.
You can try it with
template<class T> void begin( MyType<T> & t );
and see that it will fail in a similar way. Also try
template<class T> void begin( T & t );
to see that it will succeed and deduce T as MyType<int> const.
HTH.
As for the example in the paper:
std::if_< std::is_const<MyContainer>, const char*, char*>::type
begin( MyContainer&& c )
{
return c.Begin();
}
since MyContainer is a specific non-const type, the compile-time if_ will
always return char*. begin() isn't even a template. You can't expect two
different return types from a single function.
char* begin( MyContainer& c )
{
return c.Begin();
}
char const* begin( MyContainer const& c )
{
return c.Begin();
}
Note that there is no need for an rvalue reference here unless you really
want to allow people to change a non-const rvalue in a for loop:
for( char& i: MyContainer() )
{
++i; // questionable
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk