Can SFINAE be used for testing some trait classes?

We have some class templates in forms like: //========================================================== template <unsigned X> struct my_test; template <> struct my_test<0u> {}; template <unsigned X> struct my_test { typedef my_test<(X - 1u)> type; }; //========================================================== IOW, the traits express their result as a type, but omit the type for out-of-domain values. I was looking at the enable_if documentation and I was wondering if we can use SFINAE to create functions and/or function templates that will test manifestations of "my_test," but skip the test for out-of-domain values without have to explicitly exclude the values. Here, it's easy to omit "0" from the test file, but for some templates it won't be so obvious which values to exclude. (Worse, the omitted values may change between platforms!) For example, could something like //========================================================== template < unsigned X > typename my_test<X>::type print_out( my_test<X> const &x ) { std::cout << "There's a specialization at " << x << '.' << std::endl; return my_test<X>::type(); } template < typename T > void print_out( T const &x ) { std::cout << "There's no 'type' here." << std::endl; } //========================================================== with some sort of compile-time list (maybe with MPL) that runs each version of "my_test" through the best version of "print_out" be made? (This is all for replacing the macros in "integer_test.cpp" with something more up-to-date.) -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com

Daryle Walker wrote:
We have some class templates in forms like:
//========================================================== template <unsigned X> struct my_test;
template <> struct my_test<0u> {};
template <unsigned X> struct my_test { typedef my_test<(X - 1u)> type; }; //==========================================================
IOW, the traits express their result as a type, but omit the type for out-of-domain values. I was looking at the enable_if documentation and I was wondering if we can use SFINAE to create functions and/or function templates that will test manifestations of "my_test," but skip the test for out-of-domain values without have to explicitly exclude the values.
If I understood correctly, ideally, you would like to use SFINAE with a test that says "is this expression valid?". Such a facility would be quite awesome, indeed, and allowate real duck typing with fallback. It would be even better than concepts and such. (maybe concepts allow this actually?) You could probably do that by exposing basic compile-time reflection data through MPL containers for each types and operation. I have no idea, though, how you could write the expressions quite easily so that validity checks are performed automatically according to the reflection data.

2007/8/30, Mathias Gaunard <mathias.gaunard@etu.u-bordeaux1.fr>:
Daryle Walker wrote:
We have some class templates in forms like:
//========================================================== template <unsigned X> struct my_test;
template <> struct my_test<0u> {};
template <unsigned X> struct my_test { typedef my_test<(X - 1u)> type; }; //==========================================================
Do you mean something like this? template<unsigned X> struct my_test { typedef int type; }; typedef boost::mpl::list_c<unsigned,1,2,5,6,7> limit_type; template<typename T,typename Limiter> struct test_item_limit : boost::mpl::false_ {}; template<unsigned X,typename Limiter> struct test_item_limit<my_test<X>,Limiter> : boost::mpl::not_< boost::is_same< typename boost::mpl::find< Limiter, boost::mpl::integral_c<unsigned,X> >::type, typename boost::mpl::end<Limiter>::type > > { }; template < unsigned X > typename my_test<X>::type print_out( my_test<X> const &x,typename boost::enable_if<test_item_limit<my_test<X>,limit_type> >::type* =0) { std::cout << "There's a specialization at " << X << '.' << std::endl; return my_test<X>::type(); } template < typename T > void print_out( T const &x ) { std::cout << "There's no 'type' here." << std::endl; } void main() { print_out(my_test<5>()); print_out(my_test<7>()); print_out(my_test<4>()); } Regards Peder
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (3)
-
Daryle Walker
-
Mathias Gaunard
-
Peder Holt