Advertisement
kutuzzzov

Урок 10 variadic templates 2/3

Jul 19th, 2023
1,205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.43 KB | None | 0 0
  1. #include <cassert>
  2. #include <memory>
  3. #include <string>
  4.  
  5. // Шаблон ApplyToMany применяет функцию f (первый аргумент) последовательно к каждому из остальных своих аргументов
  6. template <typename f, typename... Vs>
  7. void ApplyToMany(f& func, Vs&&... vs) {
  8.     (..., func(std::forward <Vs>(vs)));
  9. }
  10.  
  11. void TestSum() {
  12.     int x;
  13.     auto lambda = [&x](int y) {
  14.         x += y;
  15.     };
  16.  
  17.     x = 0;
  18.     ApplyToMany(lambda, 1);
  19.     assert(x == 1);
  20.  
  21.     x = 0;
  22.     ApplyToMany(lambda, 1, 2, 3, 4, 5);
  23.     assert(x == 15);
  24. }
  25.  
  26. void TestConcatenate() {
  27.     using namespace std::literals;
  28.     std::string s;
  29.     auto lambda = [&s](const auto& t) {
  30.         if (!s.empty()) {
  31.             s += " ";
  32.         }
  33.         s += t;
  34.     };
  35.  
  36.     ApplyToMany(lambda, "cyan"s, "magenta"s, "yellow"s, "black"s);
  37.     assert(s == "cyan magenta yellow black"s);
  38. }
  39.  
  40. void TestIncrement() {
  41.     auto increment = [](int& x) {
  42.         ++x;
  43.     };
  44.  
  45.     int a = 0;
  46.     int b = 3;
  47.     int c = 43;
  48.  
  49.     ApplyToMany(increment, a, b, c);
  50.     assert(a == 1);
  51.     assert(b == 4);
  52.     assert(c == 44);
  53. }
  54.  
  55. void TestArgumentForwarding() {
  56.     struct S {
  57.         int call_count = 0;
  58.         int i = 0;
  59.         std::unique_ptr<int> p;
  60.         void operator()(int i) {
  61.             this->i = i;
  62.             ++call_count;
  63.         }
  64.         void operator()(std::unique_ptr<int>&& p) {
  65.             this->p = std::move(p);
  66.             ++call_count;
  67.         }
  68.     };
  69.  
  70.     S s;
  71.  
  72.     ApplyToMany(s, 1, std::make_unique<int>(42));
  73.     assert(s.call_count == 2);
  74.     assert(s.i == 1);
  75.     assert(s.p != nullptr && *s.p == 42);
  76. }
  77.  
  78. void TestArgumentForwardingToConstFunction() {
  79.     struct S {
  80.         mutable int call_count = 0;
  81.         mutable int i = 0;
  82.         mutable std::unique_ptr<int> p;
  83.         void operator()(int i) const {
  84.             this->i = i;
  85.             ++call_count;
  86.         }
  87.         void operator()(std::unique_ptr<int>&& p) const {
  88.             this->p = std::move(p);
  89.             ++call_count;
  90.         }
  91.     };
  92.  
  93.     const S s;
  94.     ApplyToMany(s, 1, std::make_unique<int>(42));
  95.     assert(s.call_count == 2);
  96.     assert(s.i == 1);
  97.     assert(s.p != nullptr && *s.p == 42);
  98. }
  99.  
  100. int main() {
  101.     TestSum();
  102.     TestConcatenate();
  103.     TestIncrement();
  104.     TestArgumentForwarding();
  105.     TestArgumentForwardingToConstFunction();
  106.     return 0;
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement