(我已经阅读了有关此问题的几个现有问题,它们似乎略有不同,并且不会让问题更清楚。)
我试图创建一个键值对的向量,其中值是通用的。 逻辑上表示我需要的代码如下:
#include <stdio.h>
#include <string.h>
#include <vector>
template <typename T>
class CCmd
{
protected:
char name[64];
T value;
public:
CCmd(char* _name, T _value)
{
strcpy(name, _name);
value = _value;
}
T getValue()
{
return value;
}
void setValue(T _value)
{
value = _value;
}
};
int main()
{
std::vector<CCmd*> vec;
vec.push_back(new CCmd<int>("gravity", 150));
vec.push_back(new CCmd<char*>("configfile", "config.cfg"));
printf("Value = %d\n", vec[0]->getValue());
printf("Config = %s\n", vec[1]->getValue());
return EXIT_SUCCESS;
}
这无法以各种方式编译,我认为它在语法上是正确的。我读了一个问题,即使用基类来封装泛型类是必需的,但是我通过创建一个指定的空类并使我的泛型类成为它的子类来尝试这个:
...
class CCmdBase
{
};
class CCmd : public CCmdBase
{
...
并且编译器抱怨CCmdBase
没有名为getValue
的成员,假定它返回泛型类型T,则意味着基类也需要是通用的让我在那里定义它,这意味着我回到了我开始的地方?
请帮忙;我在这里错过了什么?
答案 0 :(得分:4)
您的方法无法在C ++中轻松完成。很可能你的设计不正确,应该改进。很难建议确切的方法,但可能的解决方案是使用纯虚函数的抽象基类。虽然您当前的设计&#34;中的虚拟功能不能是setValue
或getValue
。因为函数签名必须与虚函数匹配。
如果您确实需要在向量中使用不同的值实现方法,请查看std::tuple
,boost::variant
和boost::any
。再次不要指望这种解决方案的使用对你来说很容易理解和直接。
答案 1 :(得分:2)
这是不正确的:std::vector<CCmd*> vec;
您必须为模板参数指定类型。 CCmd
不是类型,它是类模板的名称。例如,std::vector< CCmd<int> *> vec;
不可能有一个直接存储不同类型项目的向量。向量必须存储相同类型的项目。您正在寻找的东西称为异构容器。标准C ++没有,但您可以使用具有检索“真实”对象的函数的公共类型来模拟它。
使用运行时多态性,您对std::vector<CCmdBase *>
的想法将起作用。当然,您必须在CCmdBase
类中实际实现所需的功能。您可以在非模板类定义中包含模板函数,例如:
struct CCmdBase
{
template<typename T> T getValue()
{
return dynamic_cast< CCmd<T> & >(*this).getValue();
}
virtual ~CCmdBase() {}
};
答案 2 :(得分:0)
由于该问题最近被标记为新问题的“重复”,因此应该补充一点,由于C ++ 17,我们有了std::any
类
std::any
描述了任何类型的单个值的类型安全容器。
类模板
std::variant
表示类型安全的联合。std::variant
的实例在任何给定时间要么拥有其替代类型之一的值,要么在发生错误的情况下-没有值。
作为C ++标准的一部分。