3

c++17 introduces a nice syntax for binding pairs/tuples to individual values. Especially when iterating a map, this makes it easier to assign variable names to both the key and value. E.g.,

for( auto const [ key, value ] : my_map )
{
    foo( value );
}

However, when I loop through, I don't always need to use the key, in which case I get unused variable warnings on key.

What is the cleanest way to suppress the warnings from this context (but not others), using the gcc compiler? If I pre-declare key and value prior to the loop, then I cannot make them const. Is there some nicer approach than casting key to void inside the loop---but that still retains the [ key, value ] syntax?

schester
  • 167
  • 1
  • 2
  • 13
  • 1
    Why would you want to retain that syntax if you don't want to use `key`? Just loop with a normal range-based for loop, only use the `second` member of the `std::pair` you get by doing that, and be done with it. – cadaniluk May 28 '18 at 10:52
  • Does the warning go away if you use `auto const&[key, value]` (which means to not take a copy of every map entry) – M.M May 28 '18 at 10:52
  • 1
    Since warnings are compiler-specific, you might want to add your compiler if you really want to go with a warning here. – cadaniluk May 28 '18 at 10:53
  • @cadaniluk It seems that this syntax makes it easier to give expressive names to both the key and value, compared to naming the entire pair. – schester May 28 '18 at 10:55
  • 1
    @M.M I was imagining a case when the map entries are cheap to copy (e.g., an `std::map< uint32_t, uint32_t >`), but using a const reference does not remove the warning. – schester May 28 '18 at 10:58
  • Look into [this](https://stackoverflow.com/questions/1500064/renaming-first-and-second-of-a-map-iterator). Suppressing the unused variable could work, but I think it's just a work-around for a more fundamental problem you have, namely, the lack of expressiveness that `std::pair::first` and `std::pair::second` provide. Better tackle that problem from that angle. – cadaniluk May 28 '18 at 11:05
  • 1
    There is always the `-Wno-unused-variable` switch and `__attribute__((unused))`. I have experimented with the latter a bit, but it doesn't seem that attributes work for structured binding. Anyway, `(void) key` seems to be your best bet. Maybe write a macro like `#define UNUSED(x) (void) x` to make the code more expressive. – cadaniluk May 28 '18 at 11:06
  • 1
    It's ugly but you could do e.g. `(void) key` inside the loop to silence the warning. But unless the standard adds something like [`std::ignore`](http://en.cppreference.com/w/cpp/utility/tuple/ignore) (like it has for [`std::tie`](http://en.cppreference.com/w/cpp/utility/tuple/tie)) or adds possibility to use the `[[maybe_unused]]` [attribute specifier](http://en.cppreference.com/w/cpp/language/attributes) there's simply no way to "ignore" or omit variables in a [structured binding](http://en.cppreference.com/w/cpp/language/structured_binding). – Some programmer dude May 28 '18 at 11:08
  • @Someprogrammerdude "Is there some nicer approach than casting key to void inside the loop" -- OP wants to avoid void-casting. Nevertheless, probably the best way to go. – cadaniluk May 28 '18 at 11:09
  • I don't see why SBs couldn't allow just omitting members you don't care about, e.g. `auto const& [, value]`. Maybe someone should make a proposal – M.M May 28 '18 at 11:17
  • @M.M That is exactly what I was hoping would work, or specifically `auto const& [ /* key */, value ]`. – schester May 28 '18 at 11:20
  • Using *gcc 7.3.0*, neither `__attribute__((unused))` nor `[[maybe_unused]]` worked in this case. But I agree that the principal issue is the lack of expressiveness in std::pair::first/second combined with the inability to ignore variables in a structured binding. – schester May 28 '18 at 11:24
  • And this one: https://stackoverflow.com/questions/47005032 – schester May 28 '18 at 16:11

0 Answers0