0

How can I have access to both value and index in a c++17 ranged for loop over std::vectors?

#include <vector>
#include <iostream>

int main()
{
    std::vector<double> v{4.1,5.2,0.11,0.34};
    for(auto &&[x, idx]: v)
        std::cout<<"v["<<idx<<"]: "<<x<<std::endl;
    return 0;
}

My code fails

main.cpp:7:13: error: cannot decompose non-array non-class type ‘double’
  for(auto &&[x, idx]: v)
             ^~~~~~~~

g++ -std=c++17 main.cpp -lstdc++

version:

gcc version 7.1.0 (Ubuntu 7.1.0-10ubuntu1~16.04.york0)

ar2015
  • 5,558
  • 8
  • 53
  • 110
  • 1
    GCC 5.4 was released around the same time this feature was even accepted. – chris Jan 18 '18 at 03:07
  • In other words, use a newer compiler. – Barmar Jan 18 '18 at 03:07
  • @chris, does `sudo apt-get update && sudo apt-get upgrade` work (Ubuntu 16.04.3)? – ar2015 Jan 18 '18 at 03:10
  • @ar2015 Sorry, I have no idea whether that will do it. – Barmar Jan 18 '18 at 03:12
  • 2
    Latest compiler version or not, this won't compile. You can't get index values out of a vector. – O'Neil Jan 18 '18 at 03:14
  • @ar2015: Typically, distros won't update the major compiler version number from a simple `update` request. You need to explicitly ask for the new major version, e.g. `sudo apt-get install gcc-7` (and you may need to use `sudo update-alternatives --config gcc` or the like to ask that plain `gcc` mean `gcc-7`). – ShadowRanger Jan 18 '18 at 03:14
  • @O'Neil: Yeah, I hadn't heard about any proposals to give C++ an equivalent to Python's `enumerate` function. – ShadowRanger Jan 18 '18 at 03:16
  • 1
    @ar2015 I think Ubuntu generally waits quite a while before adding version updates to ensure stability. (Edit: I was thinking of [LTS](https://wiki.ubuntu.com/LTS).) I don't know if the latest GCC offered has the feature. Regarding O'Neil's point, there are adapters people have written to give an index and element in a range, which would look something like `for (auto &&[x, idx]: indexed(v))` if you were to use one of those implementations. – chris Jan 18 '18 at 03:18
  • @ShadowRanger, I look for direct support of the compiler and the library. No effort. – ar2015 Jan 18 '18 at 03:19
  • @ar2015: That question is asking about library support for it. If there was language support for it, there wouldn't *need* to be a question of whether the library supported it. – Nicol Bolas Jan 18 '18 at 03:21
  • @NicolBolas, that is about `c++14` this one is about `c++17`. – ar2015 Jan 18 '18 at 03:23
  • @ar2015: Click through the other [linked question](https://stackoverflow.com/q/10962290/364696) on the duplicate I linked, and you'll find another dozen similar questions linked to it (some specific to specific language standards, some asking for idiomatic solutions without specific standards). They cover it, but it's not possible with `vector` plus ranged loops alone. – ShadowRanger Jan 18 '18 at 03:26
  • @ShadowRanger, but why [here](http://en.cppreference.com/w/cpp/language/range-for) there is no effort? `for (auto&& [first,second] : mymap) {` – ar2015 Jan 18 '18 at 03:40
  • @chris, thanks updated the version. – ar2015 Jan 18 '18 at 03:42
  • 3
    @ar2015: `mymap` is almost certainly a `std::map`. The value type for them is a `pair`, which can be decomposed into `key` and `value`. That's just how `map`s work. Only `map`-like types have values that are pairs like that. – Nicol Bolas Jan 18 '18 at 03:49

0 Answers0