[libcxx-commits] [libcxx] Reapply "[libc++] Avoid constructing additional objects when using map::at" (#160738) (PR #161485)
Nico Weber via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Oct 3 07:21:09 PDT 2025
nico wrote:
Hm, ours looks different. Here's a reduced repro of ours:
```
% cat less.cc
#include <set>
#include <vector>
struct Paper {
int a { 0 };
};
namespace std {
template <>
struct less<::Paper> {
bool operator()(const ::Paper& lhs, const ::Paper& rhs) const {
return lhs.a < rhs.a;
}
};
}
template <class Key>
bool HasDuplicateItems(const std::vector<Key>& items) {
std::set<Key> items_encountered;
for (const Key& item : items) {
bool inserted = items_encountered.insert(item).second;
if (!inserted) {
return true;
}
}
return false;
}
bool f(std::vector<::Paper> p) {
return HasDuplicateItems(p);
}
```
```
% cp out/gn/include/c++/v1/__config .
% cp out/gn/include/c++/v1/__assertion_handler .
```
```
% clang++ -c less.cc -std=c++20 -isystem libcxx/include -nostdinc++ -D_LIBCPP_HARDENING_MODE_DEFAULT=_LIBCPP_HARDENING_MODE_NONE -I.
In file included from less.cc:1:
In file included from libcxx/include/set:537:
In file included from libcxx/include/__tree:40:
libcxx/include/__utility/lazy_synth_three_way_comparator.h:43:54: error: no matching function for call to object of type 'const std::less<void>'
43 | _LIBCPP_HIDE_FROM_ABI bool __less() const { return __comp_(__lhs_, __rhs_); }
| ^~~~~~~
libcxx/include/__tree:1759:20: note: in instantiation of member function 'std::__lazy_compare_result<std::less<void>, Paper, Paper>::__less' requested here
1759 | if (__comp_res.__less()) {
| ^
libcxx/include/__tree:954:38: note: in instantiation of function template specialization 'std::__tree<Paper, std::less< ::Paper>, std::allocator<Paper>>::__find_equal<Paper>' requested here
954 | auto [__parent, __child] = __find_equal(__key);
| ^
libcxx/include/set:739:93: note: in instantiation of function template specialization 'std::__tree<Paper, std::less< ::Paper>, std::allocator<Paper>>::__emplace_unique<const Paper &>' requested here
739 | _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__emplace_unique(__v); }
| ^
less.cc:21:39: note: in instantiation of member function 'std::set<Paper>::insert' requested here
21 | bool inserted = items_encountered.insert(item).second;
| ^
less.cc:30:10: note: in instantiation of function template specialization 'HasDuplicateItems<Paper>' requested here
30 | return HasDuplicateItems(p);
| ^
libcxx/include/__functional/operations.h:374:60: note: candidate template ignored: substitution failure [with _T1 = const Paper &, _T2 = const Paper &]: invalid operands to binary expression ('const Paper' and 'const Paper')
374 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
| ^
375 | noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) //
376 | -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) {
| ~
In file included from less.cc:1:
In file included from libcxx/include/set:537:
In file included from libcxx/include/__tree:40:
libcxx/include/__utility/lazy_synth_three_way_comparator.h:44:57: error: no matching function for call to object of type 'const std::less<void>'
44 | _LIBCPP_HIDE_FROM_ABI bool __greater() const { return __comp_(__rhs_, __lhs_); }
| ^~~~~~~
libcxx/include/__tree:1765:27: note: in instantiation of member function 'std::__lazy_compare_result<std::less<void>, Paper, Paper>::__greater' requested here
1765 | } else if (__comp_res.__greater()) {
| ^
libcxx/include/__tree:954:38: note: in instantiation of function template specialization 'std::__tree<Paper, std::less< ::Paper>, std::allocator<Paper>>::__find_equal<Paper>' requested here
954 | auto [__parent, __child] = __find_equal(__key);
| ^
libcxx/include/set:739:93: note: in instantiation of function template specialization 'std::__tree<Paper, std::less< ::Paper>, std::allocator<Paper>>::__emplace_unique<const Paper &>' requested here
739 | _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__emplace_unique(__v); }
| ^
less.cc:21:39: note: in instantiation of member function 'std::set<Paper>::insert' requested here
21 | bool inserted = items_encountered.insert(item).second;
| ^
less.cc:30:10: note: in instantiation of function template specialization 'HasDuplicateItems<Paper>' requested here
30 | return HasDuplicateItems(p);
| ^
libcxx/include/__functional/operations.h:374:60: note: candidate template ignored: substitution failure [with _T1 = const Paper &, _T2 = const Paper &]: invalid operands to binary expression ('const Paper' and 'const Paper')
374 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
| ^
375 | noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) //
376 | -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) {
| ~
2 errors generated.
```
Before this PR, the code built fine.
Is that `std::less` specialization invalid?
https://github.com/llvm/llvm-project/pull/161485
More information about the libcxx-commits
mailing list