15 ms·
I wish they add a new operator: "in" ... then it can be defined in maps and whatnot for lookups: if (123 in x)
by halayli 13y ago
I wish they add a new operator: "in" ... then it can be defined in maps and whatnot for lookups: if (123 in x)
- gamegoblin 13y agoI do find it odd that there isn't even a .contains(x) function and I have to use .count(x)
- halayli 13y agoC++ suffers from the too many cooks in the kitchen syndrome. They sometimes miss the basics.
- shin_lao 13y agoYou're not thinking C++ish. There is a wide range of algorithms to find/modify/replace data in containers. Let's say you have a set of ints, doing what you want is the following: std::set<int> blah; // ... some stuff happens ... if (blah.find(123) != blah.end()) { // ... } Now, you're saying, "but my container doesn't have find!". Not a problem, you can use std::find! std::vector<int> v; // ... some stuff happens ... if (std::find(v.begin(), v.end(), 123) != v.end()) { // ... } Note that v can be ANYTHING, as long it supports forward iterators (which all containers do). Now you're saying, "but it's not very efficient! The complexity of find is O(n)!" True, true. If your container is sorted, you should use binary search O(log n): if (std::binary_search(v.begin(), v.end(), 123)) { // ... } What's great about this is that it works on any container, provided it's sorted. Then, what you can do is write a metafunction that will call the member function find() when it exists or use std::find() when there's none. This will automatically, and at compile time, use the most efficient way to check for the existence of an entry.
- halayli 13y agoI am not talking about how I end up searching the container. I am talking about the syntax. Besides, how a container is searched should be abstracted away in the container's implementation and the algorithm should be documented. Compare this syntax: > if (std::find(v.begin(), v.end(), 123) != v.end()) To > if (123 in v) If in is an operator and overloaded by std::vector, then it's easy to implement.
- pfultz2 13y ago> If in is an operator and overloaded by std::vector, then it's easy to implement. However, searching a `std::vector` is not really part of its implementation. So, requiring every single range to overload an operator for trivial searching is not good, especially since there are only a few containers that have non-trivial searching. Instead, the range-based find could be specialized for containers that have non-trivial searching instead(perhaps it calls a `.find` method if available otherwise it does trivial searching). In [Linq](http://pfultz2.github.io/Linq/ http://pfultz2.github.io/Linq/), the find is specialized for mapped containers and for strings(it doesn't check for a `.find` method since that can't be done on msvc). So you can search a `std::vector` like this: std::vector<int> v = { ... }; auto it = v | linq::find(123); And you can also search the keys of a map like this: std::map<int, std::string> m = { ... }; auto it = m | linq::find(123); Plus, it has a contains function, so you can do this: if (v | linq::contains(123)) Or this: if (m | linq::contains(123)) There really is no need for a new operator just for this, since a function will suffice. However, if you really inclined to this, you could always write your own [named operator](https://github.com/klmr/named-operator)(although https://github.com/klmr/named-operator)(although I don't know if it would become standard): if (123 <in> v)
- halayli 13y agoYou can say the same thing for the new range based for loop in C++11.
- letzjuc 13y ago> how a container is searched should be abstracted away in the container's implementation lol, no, god no. I think you got the STL completely wrong.
- halayli 13y agoI see. So a map implemented using an RB Tree is not abstracting away the implementation?
- shin_lao 13y ago