Skip to content

Commit 5cb500b

Browse files
committed
Update based on internet feedback
1 parent 2b9e4cd commit 5cb500b

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

README.rst

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ you'll probably want to use a library like
490490
the older `MPL <http://www.boost.org/doc/libs/1_61_0/libs/mpl/doc/index.html>`_
491491
or the newer `boost::hana <http://www.boost.org/doc/libs/1_61_0/libs/hana/doc/html/index.html>`_.
492492

493-
More case studies to come!
493+
Some readers have taken umbrage with this example -- see my thoughts in the issues.
494494

495495
Case Study 2: Building an awesome event interface
496496
-------------------------------------------------
@@ -616,6 +616,24 @@ The big takeaway here is that ``void_t`` can be used to really easily determine
616616
Along with ``enable_if`` (which can also be used for this purpose, but the implementation is much more verbose)
617617
we can start building much more complex data structures and metafunctions.
618618

619+
Some readers have pointed out that ``count`` can be implemented with fewer template instantiations.
620+
And they're right! So check out this alternate implementation that doesn't use SFINAE at all:
621+
622+
.. code:: c++
623+
624+
/* Alternate implementation uses fewer template instantiations */
625+
template <typename... Elts>
626+
struct different_count;
627+
628+
template <typename... Elts>
629+
struct different_count<type_list<Elts...>> : std::integral_constant<int, sizeof...(Elts)> {};
630+
631+
We only define a specialization here -- you can't instantiate ``different_count`` with anything other than a
632+
``type_list``. This is an example of pattern matching, which we'll see used to good effect in the next example!
633+
The interesting thing to note here is that matching the pattern ``type_list<Elts...>`` actually unpacks ``Elts`` so
634+
that we can use it elsewhere in the template, namely as the argument of ``sizeof...``, which counts the number of
635+
types in a parameter pack.
636+
619637
Here's another metafunction that we'll be using:
620638

621639
.. code:: c++

case_study_2.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ int main() {
6868
dispatcher_2::post(spiderman);
6969
cout << endl;
7070

71-
cout << repr_1 + " has count: " << count<listeners_1>::value << endl;
72-
cout << repr_2 + " has count: " << count<listeners_2>::value << endl;
71+
cout << repr_1 + " has count: " << different_count<listeners_1>::value << endl;
72+
cout << repr_2 + " has count: " << different_count<listeners_2>::value << endl;
73+
cout << "type_list<> has count: " << different_count<type_list<>>::value << endl;
74+
// Another error -- we can *only* instantiate different_count with a type_list.
75+
// cout << "<int, int, double> has count: " << different_count<int, int, double>::value << endl;
7376
cout << endl;
7477

7578
dispatcher_1::post(JustBeforeReturn{});

case_study_2.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,17 @@ template <typename T>
3333
struct count<T, void_t<typename T::tail>> :
3434
std::integral_constant<int, 1 + count<typename T::tail>()> {};
3535

36+
/* Alternate implementation uses fewer template instantiations */
37+
template <typename... Elts>
38+
struct different_count;
39+
40+
template <typename... Elts>
41+
struct different_count<type_list<Elts...>> : std::integral_constant<int, sizeof...(Elts)> {};
3642

3743
/* has_tail predicate */
3844
template <typename T>
39-
struct has_tail : /* predicate */ /* if true */ /* if false */
40-
std::conditional<(count<T>::value == 1), std::false_type, std::true_type>::type {};
45+
struct has_tail : /* predicate */ /* if true */ /* if false */
46+
std::conditional<(different_count<T>::value <= 1), std::false_type, std::true_type>::type {};
4147

4248

4349
/* has_handler predicate */

0 commit comments

Comments
 (0)