小智 44
不,没有.最简单的解决方案是编写自己的免费模板函数来执行此操作.就像是:
#include <string>
#include <map>
using namespace std;
template <typename K, typename V>
V GetWithDef(const std::map <K,V> & m, const K & key, const V & defval ) {
typename std::map<K,V>::const_iterator it = m.find( key );
if ( it == m.end() ) {
return defval;
}
else {
return it->second;
}
}
int main() {
map <string,int> x;
...
int i = GetWithDef( x, string("foo"), 42 );
}
Run Code Online (Sandbox Code Playgroud)
C++ 11更新
目的:考虑通用关联容器,以及可选的比较器和分配器参数.
template <template<class,class,class...> class C, typename K, typename V, typename... Args>
V GetWithDef(const C<K,V,Args...>& m, K const& key, const V & defval)
{
typename C<K,V,Args...>::const_iterator it = m.find( key );
if (it == m.end())
return defval;
return it->second;
}
Run Code Online (Sandbox Code Playgroud)
Sur*_*ine 30
虽然这并没有完全回答这个问题,但我已经用这样的代码规避了这个问题:
struct IntDefaultedToMinusOne
{
int i = -1;
};
std::map<std::string, IntDefaultedToMinusOne > mymap;
Run Code Online (Sandbox Code Playgroud)
Ben*_*Ben 12
C++17 提供了try_emplace这正是这样做的。它接受值构造函数的键和参数列表,并返回一对:aniterator和 a bool.: http://en.cppreference.com/w/cpp/container/map/try_emplace
Mik*_*our 11
C++标准(23.3.1.2)指定新插入的值是默认构造的,因此map它本身不提供这样做的方法.你的选择是:
operator[]插入该默认值.更多通用版本,支持C++ 98/03和更多容器
使用通用关联容器,唯一的模板参数是容器类型本身.
支持的容器:std::map,std::multimap,std::unordered_map,std::unordered_multimap,wxHashMap,QMap,QMultiMap,QHash,QMultiHash,等.
template<typename MAP>
const typename MAP::mapped_type& get_with_default(const MAP& m,
const typename MAP::key_type& key,
const typename MAP::mapped_type& defval)
{
typename MAP::const_iterator it = m.find(key);
if (it == m.end())
return defval;
return it->second;
}
Run Code Online (Sandbox Code Playgroud)
用法:
std::map<int, std::string> t;
t[1] = "one";
string s = get_with_default(t, 2, "unknown");
Run Code Online (Sandbox Code Playgroud)
下面是一个使用包装类的类似实现,它类似于Python中get()的dict类型方法:https://github.com/hltj/wxMEdit/blob/master/src/xm/xm_utils.hpp
template<typename MAP>
struct map_wrapper
{
typedef typename MAP::key_type K;
typedef typename MAP::mapped_type V;
typedef typename MAP::const_iterator CIT;
map_wrapper(const MAP& m) :m_map(m) {}
const V& get(const K& key, const V& default_val) const
{
CIT it = m_map.find(key);
if (it == m_map.end())
return default_val;
return it->second;
}
private:
const MAP& m_map;
};
template<typename MAP>
map_wrapper<MAP> wrap_map(const MAP& m)
{
return map_wrapper<MAP>(m);
}
Run Code Online (Sandbox Code Playgroud)
用法:
std::map<int, std::string> t;
t[1] = "one";
string s = wrap_map(t).get(2, "unknown");
Run Code Online (Sandbox Code Playgroud)
无法指定默认值 - 它始终是由默认值(零参数构造函数)构造的值。
事实上,operator[]可能比您预期的要多,就好像映射中给定键的值不存在一样,它会插入一个具有默认构造函数值的新值。
template<typename T, T X>
struct Default {
Default () : val(T(X)) {}
Default (T const & val) : val(val) {}
operator T & () { return val; }
operator T const & () const { return val; }
T val;
};
<...>
std::map<KeyType, Default<ValueType, DefaultValue> > mapping;
Run Code Online (Sandbox Code Playgroud)
正如其他答案所说,该值是使用默认构造函数初始化的。但是,在简单类型(整数类型,如 int、float、指针或 POD(计划旧数据)类型)的情况下,添加值是有用的,这些值是零初始化的(或通过值初始化为零(这实际上是同样的事情),具体取决于使用的 C++ 版本)。
无论如何,底线是,具有简单类型的映射将自动对新项目进行零初始化。所以在某些情况下,无需担心显式指定默认初始值。
std::map<int, char*> map;
typedef char *P;
char *p = map[123],
*p1 = P(); // map uses the same construct inside, causes zero-initialization
assert(!p && !p1); // both will be 0
Run Code Online (Sandbox Code Playgroud)
请参阅类型名称后的括号是否与 new 有所不同?有关此事的更多详细信息。
| 归档时间: |
|
| 查看次数: |
66131 次 |
| 最近记录: |