#5991 closed Feature Requests (wontfix)
find_ptr (find wrapper)
Reported by: | Owned by: | Joaquín M López Muñoz | |
---|---|---|---|
Milestone: | To Be Determined | Component: | multi_index |
Version: | Boost 1.47.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Could you add a find wrapper to multi_index that returns value_type* instead of an iterator (and NULL if not found)?
It'd allow code like:
if (auto i = c.find_ptr("key")) { }
Change History (11)
follow-up: 2 comment:1 by , 11 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
follow-up: 3 comment:2 by , 11 years ago
Replying to joaquin:
I don't think this is sufficiently useful as to be included in the general API of Boost.MultiIndex (for one, no container in STL or Boost does it.)
Someone has to be first, right?
In any case, you can roll your own find_ptr utility:
Already got one for std::map etc, but not yet for std::set. I thought multi_index required a different function, but it can use the same as std::set. So it probably shouldn't be a member function.
follow-up: 4 comment:3 by , 11 years ago
Replying to Olaf van der Spek <olafvdspek@…>:
Replying to joaquin:
I don't think this is sufficiently useful as to be included in the general API of Boost.MultiIndex (for one, no container in STL or Boost does it.)
Someone has to be first, right?
Yes of course, but in this case I don't think the use case presented is so prominent as to deserve a dedicated built-in feature.
In any case, you can roll your own find_ptr utility:
Already got one for std::map etc, but not yet for std::set. I thought multi_index required a different function, but it can use the same as std::set. So it probably shouldn't be a member function.
What's wrong with the example find_ptr function template given above? It should work with any container providing a find member function --I don't see the need to have separate functions for map, set, etc.
follow-up: 6 comment:4 by , 11 years ago
Replying to joaquin:
Already got one for std::map etc, but not yet for std::set. I thought multi_index required a different function, but it can use the same as std::set. So it probably shouldn't be a member function.
What's wrong with the example find_ptr function template given above? It should work with any container providing a find member function --I don't see the need to have separate functions for map, set, etc.
The map variant returns a pointer to second. A variant for containers that store pointers performs an additional dereference. IMO the wrapper is useful every time you use a map like container.
follow-up: 7 comment:6 by , 11 years ago
Replying to Olaf van der Spek <olafvdspek@…>:
The map variant returns a pointer to second. A variant for containers that store pointers performs an additional dereference.
Why a pointer to second? This is not consistent with the semantics of std::map, which returns an iterator to the whole element (the key-value pair), not the value alone.
IMO the wrapper is useful every time you use a map like container.
In either case, find_ptr can be provided as an (overloaded) function, no need to have as a built-in member function. Thus my reluctance to address your request.
follow-up: 9 comment:7 by , 11 years ago
Replying to joaquin:
Why a pointer to second?
Because the key is known already.
This is not consistent with the semantics of std::map, which returns an iterator to the whole element (the key-value pair), not the value alone.
std::map doesn't have find_ptr().
IMO the wrapper is useful every time you use a map like container.
In either case, find_ptr can be provided as an (overloaded) function, no need to have as a built-in member function. Thus my reluctance to address your request.
Can it? I can't (easily) select another overload for containers (like multi_index) that don't have a pair value_type.
My find_ptr() for std::map (and std::unordered_map, boost::ptr_map, etc):
template <class T, class U> typename T::value_type::second_type* find_ptr(T& c, U v) { typename T::iterator i = c.find(v); return i == c.end() ? NULL : &i->second; } template <class T, class U> const typename T::value_type::second_type* find_ptr(const T& c, U v) { typename T::const_iterator i = c.find(v); return i == c.end() ? NULL : &i->second; } template <class T, class U> typename T::value_type::second_type find_ptr2(T& c, U v) { typename T::iterator i = c.find(v); return i == c.end() ? NULL : i->second; } template <class T, class U> const typename T::value_type::second_type find_ptr2(const T& c, U v) { typename T::const_iterator i = c.find(v); return i == c.end() ? NULL : i->second; }
follow-up: 10 comment:8 by , 11 years ago
Look at http://www.boost.org/doc/libs/1_47_0/libs/multi_index/example/bimap.cpp for example.
dictionary::iterator it=get<from>(d).find(word); if(it!=d.end()){ std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl; }
- Shouldn't it be get<from>(d).end()?
- You're not using it->first.
With bimaps though, you'd probably want to return a ptr to the pair.
follow-up: 11 comment:9 by , 11 years ago
Replying to Olaf van der Spek <olafvdspek@…>:
Replying to joaquin:
Why a pointer to second?
Because the key is known already.
This is not consistent with the semantics of std::map, which returns an iterator to the whole element (the key-value pair), not the value alone.
std::map doesn't have find_ptr().
Of course, but it has find(), which I understand you're copying semantics from, except that you return a pointer (null if no element was found) rather than an iterator (pointing to end if no element was found.)
IMO the wrapper is useful every time you use a map like container.
In either case, find_ptr can be provided as an (overloaded) function, no need to have as a built-in member function. Thus my reluctance to address your request.
Can it? I can't (easily) select another overload for containers (like multi_index) that don't have a pair value_type.
multi_index_containers don't sport a notion of second_type. But you can use the same wrapper as you're currently doing with std::set. Remember this conversarion began with your request for a member function returning a value_type* (not a pointer to the second part of the value.)
What problems are you having with defining an overload for multi_index_containers?
comment:10 by , 11 years ago
Replying to Olaf van der Spek <olafvdspek@…>:
Look at http://www.boost.org/doc/libs/1_47_0/libs/multi_index/example/bimap.cpp for example.
dictionary::iterator it=get<from>(d).find(word); if(it!=d.end()){ std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl; }
- Shouldn't it be get<from>(d).end()?
Not strictly necessary: if you don't specify the index it's as if you're using the first one.
- You're not using it->first.
So? I'm not getting your point.
comment:11 by , 11 years ago
Replying to joaquin:
Of course, but it has find(), which I understand you're copying semantics from, except that you return a pointer (null if no element was found) rather than an iterator (pointing to end if no element was found.)
True. Ideally I'd like to have find_ptr() for all containers that have a find().
IMO the wrapper is useful every time you use a map like container.
In either case, find_ptr can be provided as an (overloaded) function, no need to have as a built-in member function. Thus my reluctance to address your request.
Can it? I can't (easily) select another overload for containers (like multi_index) that don't have a pair value_type.
multi_index_containers don't sport a notion of second_type.
Right
But you can use the same wrapper as you're currently doing with std::set. Remember this conversarion began with your request for a member function returning a value_type* (not a pointer to the second part of the value.)
I don't have one yet.
What problems are you having with defining an overload for multi_index_containers?
I could easily define one with a different name, but I've no idea what enable_if code to use for automatic overload selection.
Not strictly necessary: if you don't specify the index it's as if you're using the first one.
True, but now the code assumes from is the first index.
I don't think this is sufficiently useful as to be included in the general API of Boost.MultiIndex (for one, no container in STL or Boost does it.) In any case, you can roll your own find_ptr utility: