我想弄清楚如何存储我的模板,生病写一个例子:
class cDebugInfo
{
private:
DWORD * address;
string name;
template Type;
public:
Type GetFormattedValue()
{
return *(Type*)address;
}
cDebugInfo(){}
template <class T>
cDebugInfo(DWORD Address, string Name){
address = Address;
name = Name;
Type = T;
}
};
我的目标是能够在我的数组中添加一个项目:
std::vector<cDebugInfo>DebugItems;
template <class T>
void AddItem(std::string name, DWORD Address)
{
DebugItems.push_back(cDebugInfo(Address, name));
}
cDebugInfo* GetItemByNameP(std::string name)
{
for (int i = 0; i < DebugItems.size(); i++)
{
if (DebugItems[i].name == name)
{
return &DebugItems[i];
}
}
}
所以我将这些项添加到我的数组中,如下所示:
AddItem<int>(0x1337, "Test");
AddItem<string>(0x1337, "Test2");
因此能够打电话:
GetItemByName("Test")->GetFormattedValue();
这应该返回给定地址的INT读取值,因为我添加项目时传递的模板是一个int.当然,以下内容应该将存储在我的指针指向的地址中的值作为字符串返回:
GetItemByName("Test2")->GetFormattedValue();
我需要它“记住”传递给类的模板.
注意:当我使用带有模板的GetItemByName时,其他所有工作正常,但事情是我不知道当我得到它们时它是什么模板,只有当我添加它们时.
谢谢.
最佳答案 您要求的是不可能的,因为C中的每个表达式在编译时都必须具有已知类型.考虑一下:
auto value = GetItemByName("BestItem")->GetFormattedValue();
GetItemByName(…)给了我一个cDebugInfo *,但GetFormattedValue()给了我什么?对于每个cDebugInfo *,它必须是相同的类型,以便上面的表达式可以有效,因此在运行时之前不能保留该类型.所以一般解决方案是不可能的.
但是,您可以根据要执行的操作添加特定解决方案.假设我们只想打印格式化的值.我们能做到这一点:
class cDebugInfo {
std::function<void()> printer; // type-erased functor
...
public:
template <class T>
cDebugInfo(DWORD Address, string Name){
address = Address;
name = Name;
printer = [this]{
std::cout << "Value as " << typeid(T).name() << ": "
<< *reinterpret_cast<T*>(address) << '\n';
};
}
};
这种方法称为“类型擦除”.在这种情况下,lambda“存储”类型T,但类本身只需要知道它是一个返回void的nullary函数.我们可以透露:
void printValue() { printer(); }
以便:
GetItemByValue("BestItem")->printValue();
将根据构造的类型正确打印值.