c++ - SFINAE decltype comma operator trick -
after reading matthieu's answer here, decided try myself.
my attempt fails compile because sfinae doesn't kick in , cull has_foo
function attempts access t::foo
.
error: ‘struct bar’ has no member named ‘foo’
am missing something, or i'm attempting not possible in way?
(i'm using gcc-4.7.2)
full examplar below:
#include <iostream> // culled sfinae if foo not exist template<typename t> constexpr auto has_foo(t& t) -> decltype((void)t.foo, bool()) { return true; } // catch-all fallback items no foo constexpr bool has_foo(...) { return false; } //----------------------------------------------------- template<typename t, bool> struct getfoo { static int value(t& t) { return t.foo; } }; template<typename t> struct getfoo<t, false> { static int value(t&) { return 0; } }; //----------------------------------------------------- template<typename t> int get_foo(t& t) { return getfoo<t, has_foo(t)>::value(t); } //----------------------------------------------------- struct bar { int val; }; int main() { bar b { 5 }; std::cout << get_foo(b) << std::endl; return 0; }
the primary issue here afaics using run-time reference constexpr
function parameter. replacing works fine.
#include <iostream> // culled sfinae if foo not exist template<typename t> constexpr auto has_foo(int) -> decltype(std::declval<t>().foo, bool()) { return true; } // catch-all fallback items no foo template<typename t> constexpr bool has_foo(...) { return false; } //----------------------------------------------------- template<typename t, bool> struct getfoo { static int value(t& t) { return t.foo; } }; template<typename t> struct getfoo<t, false> { static int value(t&) { return 0; } }; //----------------------------------------------------- template<typename t> int get_foo(t& t) { return getfoo<t, has_foo<t>(0)>::value(t); } //----------------------------------------------------- struct bar { int val; }; struct foo { int foo; }; int main() { bar b { 5 }; foo f { 5 }; std::cout << get_foo(b) << std::endl; std::cout << get_foo(f) << std::endl; return 0; }
Comments
Post a Comment