C++11:如何获取C++14模板化地图::查找
C++11: how to get C++14 templated map::find
我想知道是否有可能在 C++11 中实现在 C++14(根据 http://en.cppreference.com/w/cpp/container/map/find)中可用的相同模板 map::find 运算符。
template< class K > iterator find( const K& x );
我的具体问题是我的类收到一个 const char*,然后将其转换为 std::string 以将其存储在映射的键中。这对于插入方法没关系(迟早我将不得不创建字符串)。但是,当我在映射中查找项目时,我不想将 const char* 转换为字符串只是为了将其与键进行比较。字符串类已经有一个与常量字符*进行比较的方法。
std::map<std::string, int> map_;
//...
bool find(const char* value)
{
// a temporary string will be created and passed to find in C++11
// the const char* will be passed to the key comparer in C++14
return map_.find(value) != map_.end();
// in C++11 the above is equivalent to
std::string temp(value);
return map_.find(temp) != map_.end();
}
有没有办法避免 C++11 中的临时字符串?
有没有办法避免 C++11 中的临时字符串?
不。您的用例正是他们将此功能添加到 C++14 的原因。按照字面;这是提案中确切的激励示例。
任何替代的标准库解决方案,如使用 lower_bound
或其他算法,通常都会比仅分配内存具有更糟糕的性能问题。
简短的回答:"不。
长答案:不,因为您无权访问std::map
内部结构(当然,您可以编写自己的map
)。您std::map<std::string, int>
的比较器是 bool operator()(const std::string & lhs, const std::string & rhs) const
.该比较器使用std::string
。
一种可能性是使用像bool operator()(const char * lhs, const std::string & rhs) const
这样的比较器。我想这就是你的意思。
深入了解Visual Studio 2012中的std::map
实现(xutility) - 比较是在如下所示的函数中完成的
template<class _Pr, class _Ty1, class _Ty2> inline
bool _Debug_lt_pred(_Pr _Pred,
const _Ty1& _Left, _Ty2& _Right,
_Dbfile_t _File, _Dbline_t _Line)
{ // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
if (!_Pred(_Left, _Right))
return (false);
else if (_Pred(_Right, _Left))
_DEBUG_ERROR2("invalid operator<", _File, _Line);
return (true);
}
_Pred
是比较函数。您可以看到此功能与_Pred(_Left, _Right)
和_Pred(_Right, _Left)
一起使用。这就是为什么bool operator()(const char * lhs, const std::string & rhs) const
无济于事。它不是对称的。
如果你负责容器类型并愿意改变它,并且你不介意将你的键值对视为 const(即,你无意在插入元素后更新值),那么 Boost.MultiIndex 可以与ordered_unique索引一起使用来代替std::map<>
:
#include <utility>
#include <string>
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/indexed_by.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
struct transparent_less
{
using is_transparent = int;
template<typename T, typename U>
constexpr
decltype(std::declval<T&&>() < std::declval<U&&>())
operator ()(T&& lhs, U&& rhs) const
noexcept(noexcept(std::declval<T&&>() < std::declval<U&&>()))
{
return std::forward<T>(lhs) < std::forward<U>(rhs);
}
};
namespace bmi = boost::multi_index;
template<typename K, typename V>
using transparent_map = bmi::multi_index_container<
std::pair<K, V>,
bmi::indexed_by<
bmi::ordered_unique<
bmi::member<std::pair<K, V>, K, &std::pair<K, V>::first>,
transparent_less
>
>
>;
int main()
{
transparent_map<std::string, int> map;
map.emplace("foo", 1);
map.emplace("bar", 2);
std::cout << map.find("foo")->second << 'n'; // no std::string constructed
}
在线演示
除了不能改变一个值,并且没有operator[]
,这应该提供与std::map<>
相同的接口。
- 在地图和列表之间查找标准容器
- 了解标准::地图::查找
- std::在地图上查找无法正常工作并循环访问地图的键和值
- 如何使用地图::在地图上查找
- 如何在给定任意数量的整数的情况下创建一个唯一键?并使用该键存储,然后从地图中查找
- 在地图键的矢量中查找多个字符串
- 如何在具有非常量指针键的地图中通过常量指针键查找
- 在STL地图中通过参考查找并返回
- 查找地图C 没有在地图中找到已经添加的密钥
- 按值在地图中查找 - 方法在速度方面的偏好
- 带地图的 GUI C++最短路径查找器
- 在给定键 (C++) 的地图向量内查找项目
- 在地图列表中查找
- STL 地图查找无法正常工作
- 使用在地图上查找<对,int>
- 如何在将多维 int 数组映射到 C++ 中的字符串时实现在地图上查找或计数
- 地图的查找功能得到错误的结果
- 使用string_view进行地图查找
- 在地图矢量内查找对
- C++11:如何获取C++14模板化地图::查找