Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

problems with transparent Compare #8

Closed
dixlorenz opened this issue Apr 24, 2021 · 7 comments
Closed

problems with transparent Compare #8

dixlorenz opened this issue Apr 24, 2021 · 7 comments

Comments

@dixlorenz
Copy link

This code

using Map = fc::vector_set<std::string, std::less<>>;
Map m;
auto found = m.find("Key");

does not compile:

flat_impl.hpp:434:30: error: no matching function for call to object of type 'fc::impl::flat_set_base<fc::flat_set<std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >, std::__1::less<void> >, std::__1::basic_string<char>, std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >, std::__1::less<void>, int>::value_compare' (aka 'std::__1::less<void>') if (it == self()->end() || self()->value_comp()(std::ref(key), *it))

ending with

no matching function for call to object of type 'std::__1::less<void>' if (__comp(*__m, __value_))

This is on macOS, Xcode 12.4, using libc++. Using "std::ref" in the find/lower_bound function leads to less::operator(...) being ignored because of a substitution failure. When I take out std::ref it does seem to work. Using a vector_map works.

On the other hand:

std::string_view sv("Key"); auto found = m.find(sv);

works with vector_set, but not vector_map; it balks in first_compare, cannot match "reference_wrapper" (in code transparent_key_t) against basic_string_view.

@pubby
Copy link
Owner

pubby commented Apr 24, 2021

Thanks for the report!

I put out a quick fix just now, but haven't had too much time to test. Let me know if the issue persists.

@dixlorenz
Copy link
Author

My 2 examples compile now, but I can't check my actual code. I had been using a version from July 2020; the new version blows up other stuff in my code:

flat_map_base::mapped_type is declared private.

After fixing that, I get errors when doing something like

auto it = map.find("key");
it->second = "something else";

The compiler complains about it->second being const; I can't figure out why it would think that or how to fix that.

And I get some "call to member function "find" is ambiguous" errors with

template<class P> iterator insert(const_iterator hint, P&& value)
and
template<class InputIt> void insert(InputIt first, InputIt last)

when doing something like

map.insert(othermap.begin(), othermap.end());

@pubby
Copy link
Owner

pubby commented Apr 24, 2021

All iterators for flat containers are const_iterators by default, so the first behavior is intentional. You can modify the key by using operator[], by using the has member function, or by using.underlying on the iterator. The README says a little more on this.

map["key"] = "something else";
// or
*map.has("key") = "something else";
// or
auto it = map.find("key");
*it->second.underlying = "something else";

And good find! The second issue should be fixed now.

@dixlorenz
Copy link
Author

If that behavior is intentional, that would be different to a std::map (and different to before). I understand why, but it is somewhat unfortunate for generic code. For example, one of my own free functions is an "insert_or_assign" that so far worked on all maps; it does not expect a key but does a find using the transparent comparison and either sets it->second or does an emplace_hint.

Not that it does much good here, AFAICT emplace_hint ignores the hint anyway, but at least it did compile ;-)

FYI: in the last example you wrote "find" instead of "has":

if(std::string* value = map.find("qux"))

Suggestion: since has() is just a fancy wrapper around find (and not standardized), it should also use the transparent comparator.

@pubby
Copy link
Owner

pubby commented Apr 24, 2021

Yeah, it's certainly a downside to the implementation, but does provide a small amount of safety.

And that's a good idea; I went ahead and added a transparent .has version.

@dixlorenz
Copy link
Author

Thank you, AFAICT I should be able to get my code to compile again. Final question: do you intend to improve emplace_hint to actually use the hint?

@pubby
Copy link
Owner

pubby commented Apr 25, 2021

No problem. I'd like to get around to it someday but it's not a high priority for me.

@pubby pubby closed this as completed Apr 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants