我正在研究一种外部排序算法,它使用std::queue并且必须小心地限制其内存使用量.我注意到在合并阶段(使用几个std::queue固定长度),我的内存使用量增加到我预期的2.5倍左右.由于std::queue默认情况下使用std::deque它作为其底层容器,因此我运行了一些测试std::deque以确定其内存开销.以下是在发布模式下在VC++ 9上运行的结果,具有64位进程:
当向chara 添加100,000,000 s时std::deque,内存使用量增长到252,216K.请注意,100M chars(1字节)应占用97,656K,因此这是154,560K的开销.
我用doubles(8字节)重复测试,看到内存增长到1,976,676K,而100M doubles应该占用781,250K,开销为1,195,426K!
现在我明白这std::deque通常是作为"块"的链表实现的.如果这是真的,那么为什么开销与元素大小成比例(因为指针大小当然应该固定在8个字节)?为什么这么大呢?
任何人都可以解释为什么要std::deque使用如此多的危险记忆?我想我应该切换我的std::queue底层容器,std::vector因为没有开销(考虑到适当的大小reserve).我认为它的好处std::deque在很大程度上取决于它有如此巨大的开销(导致缓存未命中,页面错误等),并且std::vector鉴于整体内存使用情况,复制元素的成本可能会更低太低了.这只是std::deque微软的糟糕实现吗?
使用VC++ 2010,给出以下内容:
class Base { };
class Derived : public Base { };
template<class T> void foo(T& t); // A
void foo(Base& base); // B
Derived d;
foo(d); // calls A
foo(static_cast<Base&>(d)); // calls B
Run Code Online (Sandbox Code Playgroud)
我想在上面调用"B".我可以用演员来实现这一点Base,但为什么这是必要的?
我希望为所有不是从Base(内置类型等)派生的类型调用模板函数,但我希望从派生类型调用非模板重载Base,而不需要客户端显式转换.我也尝试使重载成为模板的特化,但在这种情况下会发生相同的行为.得到我正在寻找的东西的惯用方法是什么?
c++ templates overloading type-constraints implicit-conversion
考虑一下:
std::vector<int*> v(1, 0);
Run Code Online (Sandbox Code Playgroud)
这与VC++ 10编译良好(即使在最大警告级别也没有警告).但是,它不能在linux上使用llvm或在linux上使用gcc进行编译,从而产生类似"从不兼容的类型const int分配给int*"的错误.我不是在寻找解决方案 - 我知道第二个参数是不必要的,或者static_cast修复了错误.
我认为零可以隐式转换为任何指针类型.是什么赋予了?我可以做以下事情:
int* i = 0;
int* const& ii = 0;
const int t = 0;
i = t;
Run Code Online (Sandbox Code Playgroud)
我理解向量构造函数签名const T&在扩展时vector<int*>会变为int* const&正确吗?有人可以解释这里发生了什么,以及VC++或非VC++编译器是否正确?
std::vector<const int> vci;
vci.push_back(1);
vci[0] = 2;
Run Code Online (Sandbox Code Playgroud)
对于元素类型const int,不应该将赋值语句分配给const int&?这不能使用LLVM 3.0进行编译.为什么VC++允许它?