我强调引用不是指针,而是对象的别名.但是,我仍然不明白这对我作为一个程序员究竟意味着什么,即什么是引擎盖下的引用?
我认为理解这一点的最好方法是理解为什么我不能在地图中存储引用.
我知道我需要停止将引用视为指针的语法,只是不确定如何:/
我有一个地图,我想在每个数据类型对象成员函数上执行调用.我还知道如何在任何序列上执行此操作但是,是否可以在关联容器上执行此操作?
我能找到的最接近的答案是:Boost.Bind访问std :: for_each中的std :: map元素.但是我不能在我的项目中使用boost,那么是否有一个STL替代品,我缺少boost :: bind?
如果不可能,我想创建一个指向数据对象的指针的临时序列,然后在其上调用for_each,如下所示:
class MyClass
{
public:
void Method() const;
}
std::map<int, MyClass> Map;
//...
std::vector<MyClass*> Vector;
std::transform(Map.begin(), Map.end(), std::back_inserter(Vector), std::mem_fun_ref(&std::map<int, MyClass>::value_type::second));
std::for_each(Vector.begin(), Vector.end(), std::mem_fun(&MyClass::Method));
Run Code Online (Sandbox Code Playgroud)
它看起来太混淆了,我真的不喜欢它.有什么建议?
我正在使用带std::string钥匙的地图,虽然一切正常,但我没有达到预期的性能.我搜索了一些地方来优化和改进一些东西,当一位同事说,"那个字符串键会变慢."
我读了几十个问题,他们一直说:
"不要使用
char *键作为键"
"std::string键永远不是你的瓶颈"
"achar *和a 之间的性能差异std::string是一个神话."
我不情愿地尝试了一把char *钥匙而且有区别,差别很大.
我将问题归结为一个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <map>
#ifdef USE_STRING
#include <string>
typedef std::map<std::string, int> Map;
#else
#include <string.h>
struct char_cmp {
bool operator () (const char *a,const char *b) const
{
return strcmp(a,b)<0;
}
};
typedef std::map<const char *, int, char_cmp> Map;
#endif
Map m;
bool test(const char *s)
{
Map::iterator it = m.find(s);
return it != m.end(); …Run Code Online (Sandbox Code Playgroud) 在C++中有没有办法搜索映射的映射值(而不是键),然后返回密钥?通常,我会someMap.find(someKey)->second得到值,但在这里我想做相反的事情并获得密钥(值和密钥都是唯一的).
这可能是一个愚蠢的问题,我对C++和编程很新.我想了解几个STL容器的使用,考虑到这一点,我想知道使用std :: set vs使用矢量或地图的优点是什么?我似乎无法找到这个问题的明确答案.我注意到集合使用地图,但为什么不总是使用地图或总是使用集合.而是提供了两个非常相似的容器.提前致谢.
我想知道为什么std::map并std::set使用std::less默认仿函数来比较键.为什么不使用类似于strcmp的仿函数?就像是:
template <typename T> struct compare
{
// Return less than 0 if lhs < rhs
// Return 0 if lhs == rhs
// Return greater than 0 if lhs > rhs
int operator()(T const& lhs, T const& rhs)
{
return (lhs-rhs);
}
}
Run Code Online (Sandbox Code Playgroud)
说一个map有两个对象,用键key1和key2.现在我们要插入另一个带键的对象key3.
使用时std::less,该insert功能需要先std::less::operator()用key1和调用key3.假设std::less::operator()(key1, key3)返回false.它必须std::less::operator()再次通过键切换std::less::operator()(key3, key1),以决定是否key1等于 …
我很确定我已经在某个地方看到了这个问题(comp.lang.c ++?Google似乎也没有在那里找到它)但是这里的快速搜索似乎没有找到它所以这里是:
如果密钥不存在,为什么std :: map operator []会创建一个对象?我不知道,但对我而言,如果你与大多数其他运算符[](如std :: vector)进行比较,这似乎是违反直觉的,如果你使用它,你必须确保索引存在.我想知道在std :: map中实现这种行为的理由是什么.就像我说的那样,当使用无效密钥访问时,更像行动中的索引和崩溃(我猜是未定义的行为)会不会更直观?
看到答案后提炼我的问题:
好到目前为止,我得到了很多答案,说基本上它便宜,所以为什么不是或类似的东西.我完全同意这一点,但为什么不使用专用函数(我认为其中一条评论说在java中没有operator []并且函数被称为put)?我的观点是为什么不映射operator []像vector一样工作?如果我在向量上的超出范围索引上使用operator []我不希望它插入一个元素,即使它很便宜,因为这可能意味着我的代码中的错误.我的观点是为什么地图不一样.我的意思是,对我来说,在地图上使用operator []意味着:我知道这个密钥已经存在(无论出于什么原因,我只是插入它,我在某处有冗余,无论如何).我认为这样会更直观.
那说使用operator []执行当前行为的优点是什么(仅限于此,我同意具有当前行为的函数应该在那里,而不是operator [])?也许它以这种方式提供更清晰的代码?我不知道.
另一个答案是,它已经存在,所以为什么不保留它然后,可能当他们(stl之前的那些)选择实现它,他们发现它提供了一个优势或什么?所以我的问题基本上是:为什么选择以这种方式实现它,这意味着与其他运算符[]有点缺乏一致性.它给了什么好处?
谢谢
我有一张地图
map < string , list < string > > mapex ; list< string > li;
Run Code Online (Sandbox Code Playgroud)
如何在控制台上显示上述地图项.
我知道find方法在std :: map中找到提供的键,并将迭代器返回给元素.反正有没有找到值并获得元素的迭代器?我需要做的是检查std :: map中是否存在指定的值.我通过循环地图中的所有项目并进行比较来完成此操作.但我想知道有没有更好的办法.
这是我写的
bool ContainsValue(Type_ value)
{
bool found = false;
Map_::iterator it = internalMap.begin(); // internalMap is std::map
while(it != internalMap.end())
{
found = (it->second == value);
if(found)
break;
++it;
}
return found;
}
Run Code Online (Sandbox Code Playgroud)
编辑
如何在内部使用另一个存储值,键组合的地图.所以我可以打电话找到它吗?std :: map中的find()是否进行顺序搜索?
谢谢
我已经阅读了Merge两个STL贴图问题,虽然它很接近,但我一直在寻找像这里描述的那样的功能.
简而言之,我想将两个std::map实例(具有相同的键和值类型)合并为一个,但需要注意的是,如果对象存在于两个映射中,我想将这些值添加到一起.
是否存在可以执行此操作的现有boost,range-v3或std函数?如果没有,那么实现它的最佳方法是什么?
示例代码:
double mergePredicate(double lhs, double rhs)
{
return lhs + rhs;
}
int main()
{
std::map<int, double> mapA = { {0, 1.0}, {1, 2.0} };
std::map<int, double> mapB = { {1, 1.5}, {2, 2.5} };
// Merge maps in some way...
merge(mapA, mapB, mergePredicate);
// result: mapA == { {0, 1.0}, {1, 3.5}, {2, 2.5} }
for (const auto& p : mapA) { …Run Code Online (Sandbox Code Playgroud)