12

I would like to initialize std::vector with a range of consecutive integers without typing all of them, something like a second line, which doesn't compile, in this code snippet:

  std::vector<int> a{0, 1, 2, 3, 4, 5};
  std::vector<int> b{std::ranges::iota_view(0, 5)};  // ERROR!

Of course, I would greatly prefer:

  std::vector<int> b{0:5};

but this is not scheduled before C++41 standard. Any ideas how to do it in C++20?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Paul Jurczak
  • 7,008
  • 3
  • 47
  • 72
  • Do you have any specific restrictions that would preclude setting them in a loop? Requiring it at compile time doesn't make much sense as the storage space doesn't exist, then. – Kenny Ostrom May 16 '20 at 18:17
  • Whats wrong with 'std::vector b(5); std::iota(b.begin(), b.end(), 0)'? – Cortex0101 May 16 '20 at 18:19
  • 2
    @Cortex: Because it value-initializes the array first. – Nicol Bolas May 16 '20 at 18:20
  • 2
    @KennyOstrom I like concise notation and prefer to avoid imperative code when possible. – Paul Jurczak May 16 '20 at 18:20
  • @PaulJurczak: "*prefer to avoid imperative code when possible*" It's C++; by default, it is an imperative programming language. It can have some functional-like stuff bolted onto it, but at the bottom, it's just imperative programming. – Nicol Bolas May 16 '20 at 18:21
  • @NicolBolas I'm actively looking for `some functional-like stuff bolted onto it` – Paul Jurczak May 16 '20 at 18:23
  • @Cortex `0:5` or `0,5` is completely lost and reversed in your example. – Paul Jurczak May 16 '20 at 18:27
  • @PaulJurczak what? – Cortex0101 May 16 '20 at 18:29
  • @PaulJurczak '.. range of consecutive integers without typing all of them' that is the definition of std::iota, I get the value initialization, but is this really performance / memory critical? – Cortex0101 May 16 '20 at 18:34
  • @Cortex It's not mainly for performance. My main goal here is readability. – Paul Jurczak May 16 '20 at 18:38
  • @PaulJurczak Well std::vector has 9 constructors, but none of them do what you seek. That aside, std::iota is literally made for readability, any programmer who sees it will instantly know the contents of your vector. – Cortex0101 May 16 '20 at 18:48
  • 2
    How about the iterator constructor? `auto v = std::views::iota(0, 5); auto b = std::vector(v.begin(), v.end());` – J. Willus May 17 '20 at 17:20
  • @J.Willus That's probably the best we've got in C++, but it's embarrassingly wordy compared to many other languages. – Paul Jurczak May 17 '20 at 21:54
  • 1
    @J.Willus That's not guaranteed to work: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93651 – Pilar Latiesa May 18 '20 at 08:47

1 Answers1

9

What you’re looking for is

auto b=std::ranges::to<std::vector>(std::ranges::iota_view(0, 5));

Unfortunately, that proposal missed C++20 simply because there wasn’t time to review its wording (after a previous version that added the constructor you tried was found unworkable). Hopefully it’ll be merged—and implemented—early in the C++23 cycle.

Davis Herring
  • 36,443
  • 4
  • 48
  • 76