Skip to content

Latest commit

 

History

History
134 lines (106 loc) · 3.32 KB

249.md

File metadata and controls

134 lines (106 loc) · 3.32 KB
Info

  • Did you know that C++23 allows extended init-statement with alias-declaration in the for loop?

Example

#include <initializer_list>
#include <iostream>

int main() {
  for (using T = int; T e : {1, 2}) {
    std::cout << e; // prints 1,2
  }

  for (struct T { int x; int y; }; T e : {T{1,2}, T{3,4}}) {
    std::cout << "{" << e.x << ',' << e.y << '}'; // prints {1,2}{3,4}
  }
}

https://godbolt.org/z/Y3nvPafec

Puzzle

  • Can you implement an init-statement for the for loop which will add an anonymous struct {x,y} and an alias declaration T to it?
auto print(std::ostream& os, auto... args) -> std::ostream& {
    for (/*TODO*/ : {T{args.first, args.second}...}) {
      os << '{' << e.x << ',' << e.y << '}';
    }
    return os;
}

int main() {
  using namespace boost::ut;

  "print"_test = [] {
    "empty"_test = [] {
      std::stringstream str{};
      print(str);
      expect(std::string_view{""} == str.str());
    };

    "single pair"_test = [] {
      std::stringstream str{};
      print(str, std::pair{1,2});
      expect(std::string_view{"{1,2}"} == str.str());
    };

    "multiple pairs"_test = [] {
      std::stringstream str{};
      print(str, std::pair{1,3}, std::pair{2, 4});
      expect(std::string_view{"{1,3}{2,4}"} == str.str());
    };
  };
}

https://godbolt.org/z/zjWGhnGnf

Solutions

auto print(std::ostream& os, auto... args) -> std::ostream& {
    for (using T = struct { int x; int y; }; const T& e : std::initializer_list<T>{T{args.first, args.second}...}) {
      os << '{' << e.x << ',' << e.y << '}';
    }
    return os;
}

https://godbolt.org/z/xzd398z3n

auto print(std::ostream& os) -> std::ostream& { return os; }
auto print(std::ostream& os, auto... args) -> std::ostream& {
    for (using T = struct { int x; int y; }; const T& e : {T{args.first, args.second}...}) {
      os << '{' << e.x << ',' << e.y << '}';
    }
    return os;
}

https://godbolt.org/z/cehWYKz5a

auto print(std::ostream& os, auto... args) -> std::ostream& {
    for (using T = struct {int x; int y;}; const T & e : std::vector<T>{T{args.first, args.second}...}) {
      os << '{' << e.x << ',' << e.y << '}';
    }
    return os;
}

https://godbolt.org/z/3WaPGeG5b

auto print(std::ostream& os, auto... args) -> std::ostream& {
    for (struct T { int x; int y; }; const auto &e : std::initializer_list<T>{{args.first, args.second}...}) {
      os << '{' << e.x << ',' << e.y << '}';
    }
    return os;
}

https://godbolt.org/z/YdYsfTW1a

auto print(std::ostream& os, auto... args) -> std::ostream& {
    if constexpr (sizeof...(args) > 0) {
        for (using T = struct { int x; int y; }; auto const& e : {T{args.first, args.second}...}) {
        os << '{' << e.x << ',' << e.y << '}';
        }
    }
    return os;
}

https://godbolt.org/z/n9reaY7hE

auto print(std::ostream& os, auto... args) -> std::ostream& {
    for (using T = struct { int x; int y;}; T const & e : std::array<T, sizeof ...( args)>{T{args.first, args.second}...}) {
      os << '{' << e.x << ',' << e.y << '}';
    }
    return os;
}

https://godbolt.org/z/aKT6ocr6c