Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #85789
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Newsgroups | comp.lang.c++ |
| Subject | Re: map[string_view] not compiling |
| Date | 2022-08-03 11:34 +0200 |
| Organization | A noiseless patient Spider |
| Message-ID | <tcdff0$25305$1@dont-email.me> (permalink) |
| References | <tc8epl$t0hn$1@dont-email.me> |
On 1 Aug 2022 13:52, Paavo Helde wrote:
>
> Hi all,
>
> Let's say I have a std::map with std::string keys and want to access it
> with std::string_view keys. For lookup there is a trick to add
> std::less<> to the map definition, but it appears this does not help
> with operator[] by some reason. Maybe some expert can clarify this?
>
> Here is an example:
>
> #include <map>
> #include <string>
> using namespace std::string_view_literals;
>
>
> int main() {
>
> std::string_view key = "foo"sv;
>
> std::map<std::string, int> a;
> //auto it = a.find(key); // not compiling
> // cannot convert argument 1 from 'std::string_view' to 'const
> std::basic_string ...
>
> std::map<std::string, int, std::less<>> b;
> auto it = b.find(key); // OK now
>
> b[key] = 3; // still not compiling
> // binary '[': no operator found which takes a right-hand operand
> of type 'std::string_view'
>
> b[std::string(key)] = 3; // OK now, but may construct a std::string
> without reason
>
> }
`map::operator[]` may create a new `string` -> `int` mapping. But it
doesn't know how to create a `string` key from a `string_view`
key-comparable. Or from say a `double` key comparable, if one defined
such comparison (simply casting to `string` wouldn't even compile).
You may use code like the following, which I believe both clarifies the
issues and is one practical solution.
I chose to also address the silly `no operator[] for const` issue, but
this just-cobbled-together code lacks support for custom comparators.
#include <functional>
#include <map>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
using namespace std::literals;
namespace my {
using std::less,
std::map,
std::out_of_range,
std::string,
std::string_view,
std::forward;
template< class Key >
struct Default_key_factory_
{
template< class Key_id >
static auto make_key( Key_id&& key_id )
-> Key
{ return Key( forward<Key_id>( key_id ) ); }
};
template< class Key_, class Item_, class Key_factory_ =
Default_key_factory_<Key_> >
class Map_:
private map<Key_, Item_, less<>>
{
public:
using Key = Key_;
using Key_factory = Key_factory_;
using Item = Item_;
using Self = Map_;
using Std_map = map<Key, Item, less<>>;
using Std_map::Std_map;
using Std_map::find;
using Std_map::count;
using Std_map::lower_bound;
using Std_map::upper_bound;
using Std_map::equal_range;
template< class Key_id >
auto forced_item( const Key_id& key_id )
-> Item&
{
const auto it = Self::find( key_id );
if( it == Self::end() ) {
return Std_map::operator[]( Key_factory::make_key(
key_id ) );
}
return it->second;
}
template< class Key_id >
auto operator[]( const Key_id& key_id ) -> Item& { return
forced_item( key_id ); }
template< class Key_id >
auto operator[]( const Key_id& key_id ) const
-> const Item&
{
const auto it = Self::find( key_id );
if( it == Self::end() ) {
throw out_of_range( "const-Map_::operator[] - no such
key." );
}
return it->second;
}
};
} // namespace my
auto main() -> int
{
std::string_view key = "foo"sv;
my::Map_<std::string, int> a;
auto it_a = a.find(key); // OK
std::map<std::string, int, std::less<>> b;
auto it_b = b.find(key); // OK
//b[key] = 3; //! Gah
// binary '[': no operator found which takes a right-hand operand
of type 'std::string_view'
a[key] = 3; // OK
b[std::string(key)] = 3; // OK but may construct a std::string
without reason.
}
- Alf
Back to comp.lang.c++ | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
map[string_view] not compiling Paavo Helde <eesnimi@osa.pri.ee> - 2022-08-01 14:52 +0300
Re: map[string_view] not compiling Bo Persson <bo@bo-persson.se> - 2022-08-01 14:32 +0200
Re: map[string_view] not compiling Paavo Helde <eesnimi@osa.pri.ee> - 2022-08-01 17:11 +0300
Re: map[string_view] not compiling Öö Tiib <ootiib@hot.ee> - 2022-08-01 13:30 -0700
Re: map[string_view] not compiling Bo Persson <bo@bo-persson.se> - 2022-08-01 23:23 +0200
Re: map[string_view] not compiling Öö Tiib <ootiib@hot.ee> - 2022-08-01 22:52 -0700
Re: map[string_view] not compiling Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-08-04 08:31 -0700
Re: map[string_view] not compiling "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-08-03 11:34 +0200
Re: map[string_view] not compiling Juha Nieminen <nospam@thanks.invalid> - 2022-08-03 10:49 +0000
Re: map[string_view] not compiling "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-08-03 13:38 +0200
Re: map[string_view] not compiling Juha Nieminen <nospam@thanks.invalid> - 2022-08-04 06:16 +0000
Re: map[string_view] not compiling Paavo Helde <eesnimi@osa.pri.ee> - 2022-08-03 14:43 +0300
Re: map[string_view] not compiling "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-08-03 13:56 +0200
csiph-web