Boost logo

Boost :

Subject: Re: [boost] [Review] Boost.Type Traits Extension by Frederic Bron
From: Joachim Faulhaber (afojgo_at_[hidden])
Date: 2011-03-17 18:19:45


2011/3/17 Jeffrey Lee Hellrung, Jr. <jhellrung_at_[hidden]>:
> On 3/17/2011 1:56 PM, Joachim Faulhaber wrote:
>>
>> 2011/3/17 Jeffrey Lee Hellrung, Jr.<jhellrung_at_[hidden]>:
>>>
>>> On 3/17/2011 7:17 AM, Joachim Faulhaber wrote:
>>>>
>>>> 2011/3/17 Joachim Faulhaber<afojgo_at_[hidden]>:
>>>
>>> [...]
>>>>>
>>>>> thank you again for implementing this has_operator extension. I've
>>>>> found some problems. In the ICL I have an operator +
>>>
>>> [...]
>>>>
>>>> template<class Type>
>>>> inline typename enable_if
>>>> <is_associative_element_container<Type>, Type>::type
>>>> operator + (Type object, const Type&    operand);
>>>>
>>>>>
>>>>> and is seems that more overloads are checked valid as actually exist.
>>>>> Is this intentional?
>>>>>
>>>>> BOOST_AUTO_TEST_CASE(has_op_extension_qualifiers)
>>>>> {
>>>>> typedef int T;
>>>>> typedef interval_set<T>                 IntervalSetT;
>>>>> typedef IntervalSetT::interval_type IntervalT;
>>>>>
>>>>> // This is supposed to succeed
>>>>> BOOST_CHECK((has_operator_plus<IntervalSetT, const IntervalSetT&,
>>>>> IntervalSetT>::value));
>>>>>
>>>>> BOOST_CHECK((!is_convertible<const IntervalSetT&,
>>>>> IntervalSetT&>::value));
>>>>>
>>>>> // These are supposed to fail, but they succeed
>>>>> BOOST_CHECK((has_operator_plus<IntervalSetT, IntervalSetT&,
>>>>> IntervalSetT>::value));
>>>>> BOOST_CHECK((has_operator_plus<IntervalSetT, IntervalSetT,
>>>>> IntervalSetT>::value));
>>>>> BOOST_CHECK((has_operator_plus<IntervalSetT, IntervalSetT,
>>>>> IntervalSetT const&>::value));
>>>>> }
>>>
>>> An operator trait allows implicit conversions in the arguments.  In fact,
>>> the current implementation strategy *must* allow implicit conversions in
>>> the
>>> arguments, i.e., I wouldn't know how to detect *exact* signatures.
>>
>> Does this mean that, since
>>
>> is_convertible<T, T&>  and
>
> Not typically true, as rvalues aren't (supposed to be) implicitly
> convertible to references-to-non-const.
>
>> is_convertible<T, T const&>
>
> True, but only half the story.  We also have the conversions
>
> T & -> T const &
> T & -> T [if T is copy-constructible]
> T const & -> T [if T is copy-constructible]
>
>> has_operator_xxx comes with a built in type qualifier abstraction,
>> which means that it does never make sense to use type qualifiers with
>> has_operator_xxx<...>::value meta expressions?
>
> Here is my understanding of what *should* be happening, although I'd have to
> take a closer look at the implementation and/or wait for Frederic to
> verify/refute this assertion.
>
> You do want to use type qualifiers in the arguments if you care about
> constness or copy constructibility.  E.g., has_operator_xxx< some_type& >
> might be true while has_operator_xxx< some_type > and/or has_operator_xxx<
> some_type const & > could be false, depending on the signature of
> operator_xxx.  E.g., std::map<...>::operator[].
>
> Basically, you should invoke the has_operator_xxx metafunctions with
> argument types (including const and reference qualifiers) that match how you
> actually invoke the operator.  Same deal as with boost::result_of.

It seems like these rules should be put down in the documentation
along with some good illustrating examples.

Joachim

-- 
Interval Container Library [Boost.Icl]
http://www.joachim-faulhaber.de

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