
On 3/17/2011 1:56 PM, Joachim Faulhaber wrote:
2011/3/17 Jeffrey Lee Hellrung, Jr.<jhellrung@ucla.edu>:
On 3/17/2011 7:17 AM, Joachim Faulhaber wrote:
2011/3/17 Joachim Faulhaber<afojgo@googlemail.com>:
[...]
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. - Jeff