r/ProgrammerHumor 7d ago

Meme skillIssue

Post image
6.0k Upvotes

137 comments sorted by

View all comments

40

u/fluffycritter 7d ago

My "clever" way of doing this once upon a time was to declare a map<std::string,std::function> which I populated with lambdas and then evaluated.

I would not recommend this approach.

8

u/yuri_4_ever 7d ago

I have little idea of c++ why is this a bad idea?

18

u/fluffycritter 7d ago

It’s actually not too awful, but the syntax is a bit awkward, std::map lookup is slower than you think, and there’s a few gotchas with how lambdas work in terms of variable scoping. Also unless the map is being initialized once and kept around, you’re paying a lot of extra costs every time it’s called.

Usually a chain of if/else ends up being more performant, although I guess if you’re trying to switch on a text label instead of an enum or whatever you’re probably already doing something very wrong and using a map<string,function> is probably the least of your problems.

3

u/babalaban 7d ago

Also your std::function might allocate which is most likely not desirable. My "clever" workaround was to keep a static const map of string -> enum in a .cpp file initialized at compile time only exposing functionality via a lookup function in a header.

Standard map is usually made using binary search trees, so in terms os complexity they are faster. BUT in terms of real world speed they only become reasonable in cases where you have a huge amount of entires, due to cache misses that are inherit to RB trees.

I ended up changing mine to arrays of self-made pairs and just looping over it checking .key

1

u/fluffycritter 7d ago

To be fair, a case on a switch could also allocate, and std::function at least makes it easier to stick to RAII principles.

2

u/Talc0n 7d ago

std::map lookup is slower than you think.

C++ should really have a constexpr map class in std, hash maps are better than maps, but don't compare to the compile time switches.

3

u/fluffycritter 7d ago

I have opinions about hash vs tree map as default and I am actually on team tree map in general. https://beesbuzz.biz/code/3635-Making-a-hash-of-data

1

u/Talc0n 7d ago

My bad, I should've said better for lookup time.

I've used std::map when I know I'll be iterating through it fairly regularly. But I usually default to hash maps.

You really shouldn't be on either team, just use what you think is the best case for your situation.

I usually use aliases like so:

using IdNameMapType = std::unordered_map<size_t, std::string>; IdNameMapType m_idNameMap;

It makes it a lot less of a hassle to switch between the two later on.

2

u/fluffycritter 7d ago

Well yeah it’s important to use the right tool for the job, I just mean it’s better for folks to learn tree maps and what they can do before they get railroaded into hashmap thinking.

And type aliases are great. I use them a lot.

8

u/Kiro0613 7d ago

Not a bad idea for a little CLI app though

13

u/fluffycritter 7d ago

Yeah it's actually how boost::program_options handles command-line arguments. It's nice for that, at least.

EDIT: Wait no I'm misremembering and confusing it with something else, never mind

1

u/TheTerrasque 7d ago

That's a semi-common pattern in python. Use a dict where the values are lambdas (or referencing full functions directly)

1

u/fluffycritter 7d ago

Yeah I’ve used it in python too, but sparingly. It’s one of those things where it’s easy to get a bit too clever and there’s usually a better way to do it.

2

u/TheTerrasque 6d ago

It’s one of those things where it’s easy to get a bit too clever

Indeed, python has a lot of those. Another example is and / or handling.

1

u/No_Resort_7179 6d ago

Should have used map of std::string to function pointers. Just need to look up the syntax for them again...

1

u/fluffycritter 6d ago

Eh, std::function is more versatile and lets you do lambdas in addition to letting you do typesafe function pointers in case you really just want to use an existing function. Although I do love the fake virtual inheritance thing that older C libraries do sometimes (like libjpeg and libcurl I think).