1[#lazy_metafunction] 2[section Lazy template metafunction] 3 4A ['lazy template metafunction] is a [link metafunction template metafunction] 5that accepts [link nullary_metafunction nullary metafunction]s as arguments, 6that need to be evaluated first to get the value of the argument. 7 8For example here is a `plus` metafunction for `int` values: 9 10 template <class A, class B> 11 struct plus : 12 std::integral_constant<int, A::value + B::value> 13 {}; 14 15This metafunction takes two [link boxed_value boxed] numbers as arguments, 16unboxes them, adds their values and boxed the result again. 17 18It works when it is called with boxed numbers. For example: 19 20 static_assert( 21 plus< 22 std::intgeral_constant<int, 2>, 23 std::integral_constant<int, 2> 24 >::type::value == 4, 25 "This should work" 26 ); 27 28However, when it is called with a nullary metafunction returning the boxed 29value, it breaks: 30 31 struct nullary_metafunction_returning_2 32 { 33 using type = std::integral_constant<int, 2>; 34 }; 35 36 // Fails to compile 37 plus<nullary_metafunction_returning_2, nullary_metafunction_returning_2>::type 38 39So `plus` is ['not] a lazy template metafunction. To make it lazy, it has to 40evaluate its arguments before using them: 41 42 template <class A, class B> 43 struct lazy_plus : 44 std::integral_constant<int, A::type::value + B::type::value> 45 {}; 46 47Note that it uses `A::type::value` and `B::type::value` instead of `A::value` 48and `B::value`. It works when it is called with nullary metafunctions as well: 49 50 static_assert( 51 plus< 52 nullary_metafunction_returning_2, 53 nullary_metafunction_returning_2 54 >::type::value == 4, 55 "This should work" 56 ); 57 58Because it works with nullary metafunctions as arguments, it is a lazy template 59metafunction. 60 61[endsect] 62 63