为什么 `std::set::extract` 不像 `std::set::find` 那样支持异构查找?
Why does `std::set::extract` not support heterogeneous lookup as `std::set::find`?
#include <set>
#include <string>
#include <string_view>
using namespace std::literals;
int main()
{
auto coll = std::set<std::string, std::less<>>{"abc"s, "xyz"s};
coll.find("abc"sv); // ok
coll.extract("abc"sv); // error
}
为什么std::set::extract
not support heterogeneous lookup as std::set::find
?
C++17标准中std::set::extract()
的重载如下:
node_type extract(const_iterator position); // (1)
node_type extract(const key_type& x); // (2)
假设这里存在如下重载(在C++17标准中不存在):
template<typename K>
node_type extract(const K& x); // (3)
当 iterator
对象被传递给 extract()
时,您会期望它被隐式转换为 const_iterator
并且 (1) 将被调用,但实际上 (3 ) 将被选中。
这可以通过添加以下重载(不在 C++17 标准中)来避免:
node_type extract(iterator position); // (4)
但是,即使在这种情况下,如果您传递一个可隐式转换为 iterator
或 const_iterator
的对象,(3) 也会被调用。
这可能不是你所期望的。
P2077R2 建议引入以下带约束的重载。
template<typename K>
node_type extract(K&& x); // (5)
约束:除了 Compare::is_transparent 的存在之外,如果 K&&
可隐式转换为 iterator
或 const_iterator
,则不会选择此重载。
#include <set>
#include <string>
#include <string_view>
using namespace std::literals;
int main()
{
auto coll = std::set<std::string, std::less<>>{"abc"s, "xyz"s};
coll.find("abc"sv); // ok
coll.extract("abc"sv); // error
}
为什么std::set::extract
not support heterogeneous lookup as std::set::find
?
C++17标准中std::set::extract()
的重载如下:
node_type extract(const_iterator position); // (1)
node_type extract(const key_type& x); // (2)
假设这里存在如下重载(在C++17标准中不存在):
template<typename K>
node_type extract(const K& x); // (3)
当 iterator
对象被传递给 extract()
时,您会期望它被隐式转换为 const_iterator
并且 (1) 将被调用,但实际上 (3 ) 将被选中。
这可以通过添加以下重载(不在 C++17 标准中)来避免:
node_type extract(iterator position); // (4)
但是,即使在这种情况下,如果您传递一个可隐式转换为 iterator
或 const_iterator
的对象,(3) 也会被调用。
这可能不是你所期望的。
P2077R2 建议引入以下带约束的重载。
template<typename K>
node_type extract(K&& x); // (5)
约束:除了 Compare::is_transparent 的存在之外,如果 K&&
可隐式转换为 iterator
或 const_iterator
,则不会选择此重载。