存储初始化类的模板

时间:2015-04-16 10:42:58

标签: c++ templates

我试图找出如何存储我的模板,生病写一个例子:

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();

我需要它来记住&#34;什么模板传递给了这个类。 注意:当我使用带有模板的GetItemByName时,其他所有工作正常,但事情是我不知道当我得到它们时它是什么模板,只有当我添加它们时。 谢谢。

1 个答案:

答案 0 :(得分:2)

您要求的是不可能的,因为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';
        };
    }
};

这种方法被称为&#34;类型擦除&#34;。在这种情况下,lambda&#34;存储&#34;类型T,但类本身只需要知道它是一个返回void的nullary函数。我们可以透露:

void printValue() { printer(); }

那样:

GetItemByValue("BestItem")->printValue();

将根据构造的类型正确打印值。