
David Abrahams wrote:
Daniel Wallin <dalwan01@student.umu.se> writes:
I have been toying with a more general solution to this problem, where one can do things like:
check_dereference<T, is_convertible<mpl::_, U&> > check_add<T, T, is_convertible<mpl::_, T> >
etc.
That *might* be impressive if I could tell what those expressions were supposed to mean ;-)
The metafunction class is applied to the result type of the operation, and is required to have boolean result. For instance: struct X { void operator+(X const&) const; X operator+(int) const; }; template<class T> struct Y : mpl::false_ {}; template<> struct Y<X> : mpl::true_ {}; check_add<X, X, Y<mpl::_> >::type // X + X, invokes Y<void> -> false check_add<X, int, Y<mpl::_> >::type // X + int, invoked Y<X> -> true Using this we could express more complicated concept checks. For instance: "The Lvalue Iterator concept adds the requirement that the return type of operator* type be a reference to the value type of the iterator." template<class Iterator> struct is_iterator_lvalue_dereferencable : check_dereference< Iterator , is_same< mpl::_ , typename iterator_value<Iterator>::type& > > { }; -- Daniel Wallin