Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost][enable_if] SFINAE and decltype
From: Jeremiah Willcock (jewillco_at_[hidden])
Date: 2011-04-28 15:55:44


On Thu, 28 Apr 2011, Germán Diago wrote:

> Hi all,
>
> I'm having a hard time trying to figure out how to make a code like
> this to improve error
> messages through static_assert. I want that when the function
> instantiation fails, the other
> function's static assert fails. I don't know how to do it. I began
> with something like this:
>
> template <class Range, class T>
> Range find(Range && haystack, const T & elem)
> {
> static_assert(std::is_convertible<decltype (elem ==
> haystack.front())>::value,
> "elem and haystack must be equality comparable");
> while (!haystack.empty() && !(haystack.front() == elem))
> haystack.popFront();
> return haystack;
> }
>
>
> But that didn't work since when decltype is applied to an invalid
> expression, SFINAE doesn't trigger
> in the function body.
>
>
> So now I'm trying an alternative like this, but I don't know how to express it:
>
> template <class Range, class T>
> Range find(Range && haystack, const T & elem,
> decltype (elem == haystack.front()) * = 0)
> {
> while (!haystack.empty() && !(haystack.front() == elem))
> haystack.popFront();
> return haystack;
> }
>
>
>
> template <class Range, class T>
> Range find(Range && haystack, const T & elem,
> !decltype (elem == haystack.front()) * = 0)
> {
> static_assert(...,
> "haystack.front() and elem must be equality comparable");
> return haystack;
> }

If you want the function to fail anyway, why not use the first version
(that doesn't SFINAE on errors)? Otherwise, try changing your !decltype
version to:

template <class Range, class T>
Range find(Range && haystack, const T& elem, ...) {
   // body
}

I think that gets the specialization order correct, but I'm not completely
sure.

-- Jeremiah Willcock


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net