如何比较boost :: variant以使其成为std :: map的关键?似乎没有为boost :: variant定义operator <()
每次在std :: map中插入一对,其键是std :: string时,它会生成两个副本.您可以避免使用原始指针,但它是异常不安全的.有没有办法使用智能指针而不是原始指针?
示例代码:
// To compile: g++ -std=c++0x exmaple.cpp -o example
#include <iostream>
#include <string>
#include <map>
#include <memory>
class StringSquealer: public std::string
{
public:
StringSquealer(const std::string s) : std::string(s) {}
StringSquealer(const StringSquealer&)
{
std::cout << "COPY-CONSTRUCTOR" << std::endl;
}
};
int main()
{
// Inefficient
std::map<StringSquealer,int> m1;
m1[StringSquealer("key")] = 1;
std::cout << "---" << std::endl;
// Exception-unsafe
std::map<StringSquealer*,int> m2;
m2[new StringSquealer("key")] = 1;
//Ideal??
std::map<std::unique_ptr<StringSquealer>,int> m3;
std::unique_ptr<StringSquealer> s(new StringSquealer("key"));
//!m3[std::move(s)] = 1; // No compile
} …Run Code Online (Sandbox Code Playgroud) 我有一个奇怪的问题.我正在使用工厂注册模式,它在内部引用std :: map.我正在将这种方法用于多个组件,并且在不同的编译单元(即.cpp文件)中的多个点处进行注册.这发生在静态变量初始化时(在调用'main'之前).出于一些奇怪的原因,我指的是一个段错误
map[key] = value;
(基本上当我注册一个特定的pfn时).现在,如果我在同一个编译单元中移动特定麻烦组件的注册,一切正常.再说一遍,如果我只撤回一个组件的注册,我会得到一个段错误.
我不得不说,这不是我第一次使用这种模式,它适用于其他组件的相同可执行文件(即,在初始化时没有问题的情况下,在另一个工厂类型的多个.cpp上传播的组件使用基本相似的源代码) .
我该怎么办?现在我已经将组件的注册保留在同一个.cpp中(并且它可以完美地工作).我怎样才能更好地调查?
我正在使用g ++(Ubuntu/Linaro 4.4.4-14ubuntu5)4.4.5
在stacktrace下面
0x00007ffff793da1a in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib/libstdc++.so.6
(gdb) bt
#0 0x00007ffff793da1a in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib/libstdc++.so.6
#1 0x0000000000413fe9 in std::_Rb_tree_iterator, std::allocator > const, http::servlet* (*)()> >::operator-- (
this=0x7fffffffdff0) at /usr/include/c++/4.4/bits/stl_tree.h:199
#2 0x000000000041379d in std::_Rb_tree, std::allocator >, std::pair, std::allocator > const, http::servlet* (*)()>, std::_Select1st, std::allocator > const, http::servlet* (*)()> >, std::less, std::allocator > >, std::allocator, std::allocator > const, http::servlet* (*)()> > >::_M_insert_unique (this=0x632a20, __v=...) at /usr/include/c++/4.4/bits/stl_tree.h:1179
#3 0x00000000004125f2 in std::_Rb_tree, std::allocator >, std::pair, … 如何声明迭代器
std::map <T, Point <T> *> ,
Run Code Online (Sandbox Code Playgroud)
哪里:
template <typename T>
struct TList
{
typedef std::vector < std::map <T, Point <T> *> > Type;
};
Run Code Online (Sandbox Code Playgroud)
在以下代码中
int main ()
{
....
std::map <T, Point <T> *> ::iterator i_map; //Error
...
}
Run Code Online (Sandbox Code Playgroud)
g ++显示此错误:
error: dependent-name ` std::map<T,Point<T>*,std::less<_Key>,std::allocator<std::pair<const T, Point<T>*> > >::iterator' is parsed as a non-type, but instantiation yields a type
note: say `typename std::map<T,Point<T>*,std::less<_Key>,std::allocator<std::pair<const T, Point<T>*> > >::iterator' if a type is meant
Run Code Online (Sandbox Code Playgroud) 我有一个运算符<()方法的问题,这是std :: map所必需的.我使用结构作为复合键,如下所示:
struct MyKey {
std::string string1;
std::string string2;
std::string string3;
unsigned int uint1;
friend bool operator<(const MyKey& mk1, const MyKey& mk2)
{
return mk1.string1 < mk2.string1 && mk1.string2 < mk2.string2 &&
mk1.string3 < mk2.string3 && mk1.uint1 < mk2.uint1;
}
}
Run Code Online (Sandbox Code Playgroud)
如前所述,我想使用具有4个值的复合键,但我不知道如何为运算符< method 实现此功能.我观察到一次只存储1个值!
任何人都可以告诉我正确的情况如何?
提前致谢!
我正在创建一个std::map<a,b>定义排序标准的地方a::operator<
有没有办法在某些时候更改地图的类型,以便从现在开始通过另一个排序算法进行排序a?它还需要重新排序地图的当前内容
谢谢
本质上,我想要一个容器,其中一个元素可以被许多键访问.这可以通过定义一些用作地图键类型的多键类来完成,但由于这样的解决方案不允许修改已经插入的元素的键,我无法为其创建新的别名现有条目.
我很欣赏,std::map为了订购,密钥需要保持不变,但为什么要存在这种限制std::unordered_map呢?
如果需要,我想我可以使用指针图,但是有更好,更优雅的解决方案吗?
编辑:谢谢你清除Andrei,Xeo.尼科尔,关于我应该使用什么容器的任何建议?
我有这样的方法:
std::map<std::string, int> container;
void myMap(std::initializer_list<std::pair<std::string, int>> input)
{
// insert 'input' into map...
}
Run Code Online (Sandbox Code Playgroud)
我可以像这样调用这个方法:
myMap({
{"foo", 1}
});
Run Code Online (Sandbox Code Playgroud)
我如何转换我的自定义参数并插入到地图中?
我试过了:
container = input;
container(input);
Run Code Online (Sandbox Code Playgroud)
但是不要工作,因为地图的参数只是,std::initializer_list并且那里没有std::pair.
谢谢你们.
当我尝试在地图中插入一个元素时,我发生了一些奇怪的事情
main.cpp中
S3Wrapper wrapper = S3Wrapper::getS3Wrapper();
int main(){
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以基本上只为S3Wrapper调用单例
S3Wrapper.hpp
class S3Wrapper
{
S3Wrapper(std::string bucketName);
public:
~S3Wrapper();
static S3Wrapper &getS3Wrapper(std::string name = BUCKET_NAME);
}
Run Code Online (Sandbox Code Playgroud)
和S3Wrapper.cpp
static std::map<std::string, S3Wrapper*> _wrapperMap;
S3Wrapper& S3Wrapper::getS3Wrapper(std::string name)
{
auto it = _wrapperMap.find(name);
if (it == _wrapperMap.end())
{
auto t = new S3Wrapper(name);
_wrapperMap[name] = t;
return *(_wrapperMap[name]);
}
return *(it->second);
}
Run Code Online (Sandbox Code Playgroud)
当我编译时,我没有任何错误/警告但是程序段错误:
g++ main.cpp S3Wrapper.cpp -std=c++0x -ls3 -g3
Run Code Online (Sandbox Code Playgroud)
gdb的结果
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7937c4a in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) …Run Code Online (Sandbox Code Playgroud) 我可以做的一件事是分配一个大小为n的向量并存储所有数据,然后使用sort(begin(),end())对其进行排序.另外,我可以继续将数据放在一个地图中或设置自己订购的数据,这样我就不用事了.但在这种情况下,由于重新排列(我猜),插入元素可能会更昂贵.
因此,对于大范围的n(对象的数量)来说,这是最短时间的最佳选择