Re: Using SFINAE with C++14 generic lambdas
On 2015-04-01 14:26, lorenzo.caminiti@googlemail.com wrote:> Hello all,
Is it possible to use C++14 generic lambdas together with SFINAE, for
example to check if a class has a member function of a given name?
No (and this is actually not a problem related to C++ lambdas).
This problem is well solved by declaring templates outside the local
scope. But I am wondering if now with C++14 generic lambda the same
can be archived with locally declared constructs... but I didn't have
much luck with this :(
For example:
#include <type_traits>
#include <iostream>
// This works but...
//template< class T >
//static auto check ( T* o, T* oo ) -> decltype(o->f(),
std::true_type());
template< typename T >
static std::false_type check ( T* o, ... );
int main ( ) {
// ... this doesn't work :(
auto check = [] ( auto o, auto oo ) ->
decltype(o->f(), std::true_type()) {};
struct x { void f (); };
static_assert(decltype(check((x*)0, (x*)0))::value, "x::f");
struct y {};
static_assert(!decltype(check((y*)0, (y*)0))::value, "!y::f");
return 0;
}
On clang the above gives an error like this:
04.cpp:20:29: error: no matching function for call to object of type
'<lambda at 04.cpp:13:18>'
static_assert(!decltype(check((y*)0, (y*)0))::value, "!y::f");
^~~~~
04.cpp:13:18: note: candidate template ignored: substitution failure
[with
$auto-0-0 = y *, $auto-0-1 = y *]: no member named 'f' in 'y'
auto check = [] ( auto o, auto oo ) ->
This cannot work, because the concept of overload resolution does only
exist for function (templates), it does not exist for objects or between
objects and functions. What happens in your code is that the name of the
function-local variable "check" hides the previously declared function
(template) name. This becomes more obvious, if you move the definition
of the lambda in the same global scope where the function template is
declared. You will notice now a different compiler error along the lines of
"error: redefinition of 'check' as different kind of symbol"
I noted above that this is not a problem related to lambdas, because it
occurs in all cases where you try to declare function together with
objects, so it would occur in some other user-defined function object
with the same name as another function in the same namespace.
For mechanisms that depend on function declarations (like overload
resolution) you need to use functions.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]