eif_lazy.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Boost enable_if library
  2. // Copyright 2003 (c) The Trustees of Indiana University.
  3. // Use, modification, and distribution is subject to the Boost Software
  4. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
  7. // Jeremiah Willcock (jewillco at osl.iu.edu)
  8. // Andrew Lumsdaine (lums at osl.iu.edu)
  9. #include <boost/utility/enable_if.hpp>
  10. #include <boost/type_traits/is_same.hpp>
  11. #include <boost/detail/lightweight_test.hpp>
  12. using boost::enable_if_c;
  13. using boost::lazy_enable_if_c;
  14. // This class provides a reduced example of a traits class for
  15. // computing the result of multiplying two types. The member typedef
  16. // 'type' in this traits class defines the return type of this
  17. // operator. The return type member is invalid unless both arguments
  18. // for mult_traits are values that mult_traits expects (ints in this
  19. // case). This kind of situation may arise if a traits class only
  20. // makes sense for some set of types, not all C++ types.
  21. template <class T> struct is_int {
  22. BOOST_STATIC_CONSTANT(bool, value = (boost::is_same<T, int>::value));
  23. };
  24. template <class T, class U>
  25. struct mult_traits {
  26. typedef typename T::does_not_exist type;
  27. };
  28. template <>
  29. struct mult_traits<int, int> {
  30. typedef int type;
  31. };
  32. // Next, a forwarding function mult() is defined. It is enabled only
  33. // when both arguments are of type int. The first version, using
  34. // non-lazy enable_if_c does not work.
  35. #if 0
  36. template <class T, class U>
  37. typename enable_if_c<
  38. is_int<T>::value && is_int<U>::value,
  39. typename mult_traits<T, U>::type
  40. >::type
  41. mult(const T& x, const U& y) {return x * y;}
  42. #endif
  43. // A correct version uses lazy_enable_if_c.
  44. // This template removes compiler errors from invalid code used as an
  45. // argument to enable_if_c.
  46. #if 1
  47. template <class T, class U>
  48. typename lazy_enable_if_c<
  49. is_int<T>::value & is_int<U>::value,
  50. mult_traits<T, U>
  51. >::type
  52. mult(const T& x, const U& y) {return x * y;}
  53. #endif
  54. double mult(int i, double d) { return (double)i * d; }
  55. int main()
  56. {
  57. BOOST_TEST(mult(1, 2) == 2);
  58. BOOST_TEST(mult(1, 3.0) == 3.0);
  59. return boost::report_errors();
  60. }