
On Mon, Oct 6, 2008 at 7:02 AM, Joel Falcou <joel.falcou@u-psud.fr> wrote:
Mathias Gaunard a écrit :
As of today, in GCC 4.4, you can do something equivalent but have to be significantly more verbose:
template<typename T, size_t Cond> struct foo_type { typedef decltype(((T*)0)->foo()) type; };
template<typename T> typename foo_type<T, sizeof(((T*)0)->foo() > 0)>::type foo(T&& t) { return t.foo(); }
(You cannot put decltype directly in the return type because of name mangling issues)
Can't this be packaged into some macro like BOOST_HAS_XXX ?
Yeah, that's kind of what I was getting at by a compile time eval or is_compilable. But those are misnomers. You're not checking validity for whole blocks or statements, just single expressions with a given type. But yeah, you could wrap the general boilerplate in a preprocessor metafunction and maybe call it something like BOOST_HAS_EXPRESSION. Of course, the expressions I'm interested in would check for a concept, for example, an expression like function_requires<ForwardRange<T> >(). So for a boolean metafunction that checks if a type models some concept, the final C++0x code (for platforms without concept language support) would be something like: template<class ConceptCeck, class T> struct has_concept { typedef char (&yes)[1]; typedef char (&no)[2]; template<typename T> static no test(...); template<typename T> static yes test(T* t) -> decltype(function_requires<ConceptCheck<T> >()); public: static const bool value = sizeof(test<T>(0)) == sizeof(yes); typedef boost::mpl::bool_<value> type; }; BOOST_MPL_ASSERT((has_concept<ForwardRange, vector<int> >)); For platforms with concept language support, you would use CRFINAE instead of expression SFINAE on the two test() functions. At least, this is the general idea. I assume something like this would work... Daniel