情况是我编写了一个汇编程序,我使用std::unordered_multimap
容器来存储所有不同的指令,其中实际的助记符是我的密钥到地图中关联的值是一个自定义结构,其中包含一些关于参数的附加信息等。
由于我不需要在运行时对此查找进行任何更改,我认为我将其声明为static和const,并将所有值手动放在initializer_list中。
总之它看起来像这样:
typedef std::wstring STRING;
static const
std::unordered_multimap<STRING, ASM_INSTRUCTION> InstructionLookup = {
// { MNEMONIC, { Opcode1, Opcode2, Param1Type, Param2Type, Param3Type, NrBytes, Bt1, Bt2, Bt3, Bt4, NoRexW, InvalidIn64Bit, InvalidIn32Bit } },
{ L"AAA",{ ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false } },
{ L"AAD",{ ot_none, ot_none, par_noparam, par_noparam, par_noparam, 2, 0xD5, 0x0A, 0x00, 0x00, false, true, false } },
{ L"AAD",{ ot_ib, ot_none, par_imm8, par_noparam, par_noparam, 1, 0xD5, 0x00, 0x00, 0x00, false, true, false } },
{ L"AAM",{ ot_none, ot_none, par_noparam, par_noparam, par_noparam, 2, 0xD4, 0x0A, 0x00, 0x00, false, true, false } },
...
我现在的问题是,已经实施了很多指令(目前有1,225个) 因此,当我使用Visual Studio运行代码分析时,它告诉我构造函数超过了98,000 / 16,384字节的堆栈,因为构造函数首先将所有这些条目放在堆栈上,然后再进行处理。
我现在的问题是如何直接在堆上初始化所有空间,最好不必重写它。
答案 0 :(得分:1)
我认为emplace正是您所寻找的:
InstructionLookup.emplace(std::piecewise_construct, std::forward_as_tuple(L"sXs"), std::forward_as_tuple(ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false));
我尝试尽可能地保留您的语法,并将Boost.Assign实现版本从here更改为使用完美转发:
template <typename T, typename U>
class create_unmap
{
private:
std::unordered_multimap<T, U> m_map;
public:
template <typename ...Args>
create_unmap(Args&&... _Val)
{
m_map.emplace(std::forward<Args>(_Val)...);
}
template <typename ...Args>
create_unmap<T, U>& operator()(Args&&... _Val)
{
m_map.emplace(std::forward<Args>(_Val)...);
return *this;
}
operator std::unordered_multimap<T, U>()
{
return std::move(m_map);
}
};
您可以使用以下语法声明地图:
static const std::unordered_multimap<STRING, ASM_INSTRUCTION> InstructionLookupt = create_unmap<STRING, ASM_INSTRUCTION>
(std::piecewise_construct, std::forward_as_tuple(L"AAA"), std::forward_as_tuple(ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false))
(std::piecewise_construct, std::forward_as_tuple(L"AAD"), std::forward_as_tuple(ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false))
(std::piecewise_construct, std::forward_as_tuple(L"AAD"), std::forward_as_tuple(ot_none, ot_none, par_noparam, par_noparam, par_noparam, 1, 0x37, 0x00, 0x00, 0x00, false, true, false));