2

During work I endountered a problem with a for_each loop.

I have a std::unordered_map inside a struct which holds another object. When I use std::for_each i can't use auto& to call the current element, the compiler can't deduce the type. On the other hand if I avoid auto& and use std::unordered_map<std::size_t, Foo>::value_type& everything works as expected.

I'm fine with that, but i don't understand why the compiler can't deduce the type here... you can find this example from below here on compiler explorer: https://godbolt.org/z/3eehKsxs7

#include <iostream>
#include <unordered_map>
#include <algorithm>

struct Foo {
    template<typename T>
    T do_some_work()
    {
        // do some work .. 
        T t; 
        return t;
    }
};

struct map_manager {
    std::unordered_map<std::size_t, Foo> m_map;
};

int main() 
{
    Foo f1;

    map_manager mm;

    mm.m_map[1] = f1;
    mm.m_map[2] = f1;
    mm.m_map[3] = f1;


    std::for_each(std::begin(mm.m_map), std::end(mm.m_map), 
    //[](std::unordered_map<std::size_t, Foo>::value_type& current){ // works
    [](auto& current){                                           // doesn't work
        auto bar = current.second.do_some_work<int>();
    });   
    
}
ThoSe
  • 21
  • 5
  • 1
    with `current.second.template print_something()` it builds with auto for the lambda. no idea why there's a difference though – Mat Apr 28 '22 at 15:23
  • 2
    The example you linked does not have any problem with deducing anything. It shows a compilation error because you need `template` before `do_some_work()`. – François Andrieux Apr 28 '22 at 15:29
  • 1
    TL;DR of the dupe: `do_some_work` is a dependent name, so you need `auto bar = current.second.template do_some_work();` to tell the compier `do_some_work` is a template. – NathanOliver Apr 28 '22 at 15:29
  • thanks!!! in the meantime i compiled with clang and saw that compiler message, however haven't seen this so far. thanks again its good now for me – ThoSe Apr 28 '22 at 15:37

0 Answers0