|
Boost : |
Subject: Re: [boost] C++11 decltype/SFINAE puzzler
From: Eric Niebler (eric_at_[hidden])
Date: 2012-08-13 16:03:33
On 8/12/2012 7:50 PM, Eric Niebler wrote:
> Great! And very simple. It doesn't move the error close to the API
> boundary, but other than that, it fits the bill. Thanks. If I end up
> using this technique in my code, I will credit you.
I think I have a very nice solution now. It combines my earlier approach
with with Paul Fritz's. See the attached.
You define your callables with the RETURNS macro and a try_call function
object wrapper, like this:
struct S0
{
template<typename T>
auto operator()(T t) const RETURN( t + 1 )
};
struct S1
{
template<typename T>
auto operator()(T t) const RETURN( try_call<S0>()(t) )
};
struct S2
{
template<typename T>
auto operator()(T t) const RETURN( try_call<S1>()(t) )
};
Then, you simply invoke your function object:
auto i = S2()(32); // ok
auto x = S2()(foo()); // compile-time error
The compile error is transported to the API boundary. The result is a
very short and precise error message about the cause of the failure.
Clang gives this:
> $ /usr/local/bin/clang++ -std=gnu++11 sfinae_error.cpp
> sfinae_error.cpp:28:26: error: no matching function for call to object of type 'S0'
> typedef decltype(std::declval<Fun>()(std::declval<Args>()...)) type;
> ^~~~~~~~~~~~~~~~~~~
> sfinae_error.cpp:91:14: note: in instantiation of member function 'sfinae_error<S0 (foo &)>::what'
> requested here
> auto x = S2()(foo());
> ^
> sfinae_error.cpp:70:10: note: candidate template ignored: substitution failure [with T = foo]:
> invalid operands to binary expression ('foo' and 'int')
> auto operator()(T t) const RETURN( t + 1 )
> ^ ~~~~~~~~~~~~~~~
> 1 error generated.
Note that no information about the intermediate calls (S2, S1) shows up
in the backtrace. Just the error you care about.
GCC-4.7 gives a similarly terse error message. This, I think, is what
I've been looking for.
-- Eric Niebler BoostPro Computing http://www.boostpro.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk