forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
https://godbolt.org/z/jTGz5sTPP
#include <cassert>
#include <flat_map>
#include <string>
struct StartsWith {
explicit StartsWith(char ch) : lower_(1, ch), upper_(1, ch+1) {}
struct Less {
using is_transparent = void;
bool operator()(const std::string& a, const std::string& b) const { return a < b; }
bool operator()(const StartsWith& a, const std::string& b) const { return a.upper_ <= b; }
bool operator()(const std::string& a, const StartsWith& b) const { return a < b.lower_; }
//bool operator()(const StartsWith& a, const StartsWith& b) const;
};
private:
std::string lower_;
std::string upper_;
};
int main() {
using M = std::flat_map<std::string, int, StartsWith::Less>;
M m = { {"alpha", 1}, {"beta", 2}, {"epsilon", 3}, {"eta", 4}, {"gamma", 5} };
auto begin = m.begin();
assert(m.equal_range(StartsWith('b')) == std::pair(begin+1, begin+2));
}
libc++ trunk complains:
__flat_map/flat_map.h:1035:19: error: no matching function for call to object of type 'const __lower_bound'
1035 | auto __it = ranges::lower_bound(__self.__containers_.keys, __key, __self.__compare_);
| ^~~~~~~~~~~~~~~~~~~
Ultimately because:
__concepts/invocable.h:34:29: note: because 'invocable<StartsWith::Less &, StartsWith &, StartsWith &>' evaluated to false
34 | concept regular_invocable = invocable<_Fn, _Args...>;
| ^
But [associative.reqmts] doesn't seem to require that any value c
of type X::key_compare
should model std::regular_invocable
— it requires merely that expressions such as c(x, kx)
and c(kx, x)
should be well-formed, and that c
should induce a strict weak ordering.
Uncommenting the member function operator()(const StartsWith& a, const StartsWith& b)
above makes the test compile; but that shouldn't be necessary, as flat_map
never has any reason to compare one StartsWith
object against another.
Metadata
Metadata
Assignees
Labels
No labels