
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