简体   繁体   English

模板类的向量

[英]Vector of template class

(I've read several existing questions regarding this issue and they seem slightly different and don't make the issue any clearer to me.) (我已经阅读了几个关于这个问题的现有问题,它们似乎略有不同,并没有让我更清楚这个问题。)

I'm trying to create a vector of key-value pairs in which the value is generic.我正在尝试创建一个键值对向量,其中的值是通用的。 The code which logically indicates what I need follows:逻辑上表明我需要的代码如下:

#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;
}

This fails to compile in every way I think it would be syntactically correct.这无法以我认为在语法上正确的方式进行编译。 I read on one question that using a base class to encapsulate the generic class is required, however I tried this by creating an empty class as indicated and made my generic class a subclass of it:我读到一个问题,需要使用基类来封装泛型类,但是我尝试通过创建一个空类来实现这一点,并将泛型类设为它的子类:

...
class CCmdBase
{
};

class CCmd : public CCmdBase
{
...

and the compiler complains that CCmdBase doesn't have a member named getValue which, given that it returns the generic type T, would mean that the base class would also need to be generic for me to define it in there, which means that I'm back where I'm started?并且编译器抱怨CCmdBase没有名为getValue的成员,鉴于它返回泛型类型 T,这意味着基类也需要是泛型的,我才能在那里定义它,这意味着我我回到我开始的地方了吗?

Please help;请帮忙; what am I missing here?我在这里错过了什么?

Your approach cannot be easily done in C++.您的方法在 C++ 中无法轻松完成。 Most probably your design is incorrect and should be improved.很可能您的设计不正确,应该改进。 It is difficult to advise exact way, but possible solution to have abstract base class with pure virtual functions.很难建议确切的方法,但可能的解决方案是使用纯虚函数的抽象基类。 Though your virtual function cannot be setValue or getValue in your current "design" as function signature must match for virtual functions.尽管您的虚拟函数在您当前的“设计”中不能是setValuegetValue ,因为函数签名必须与虚拟函数匹配。

In case you really need to implement approach with different values in the vector look into std::tuple , boost::variant and boost::any .如果您真的需要在向量中使用不同的值实现方法,请查看std::tupleboost::variantboost::any Again do not expect that usage of such solution will be easy to understand and straightforward for you.再次不要指望这种解决方案的使用对您来说很容易理解和直接。

This is incorrect: std::vector<CCmd*> vec;这是不正确的: std::vector<CCmd*> vec;

You must specify a type for the template parameter.您必须为模板参数指定类型。 CCmd isn't a type, it's the name of a class template. CCmd不是类型,而是类模板的名称。 For example , std::vector< CCmd<int> *> vec;例如, std::vector< CCmd<int> *> vec;

It's not possible to have a vector which directly stores items of different types.不可能有一个直接存储不同类型项目的向量。 The vector must store items of the same type.向量必须存储相同类型的项目。 The thing you are looking for is called a heterogenous container .您正在寻找的东西称为异构容器 Standard C++ doesn't have any, but you can simulate one by using a common type which has functions to retrieve the "real" object.标准 C++ 没有,但您可以通过使用具有检索“真实”对象的函数的通用类型来模拟一个。

Your idea of std::vector<CCmdBase *> will work, using runtime polymorphism.您对std::vector<CCmdBase *>想法将起作用,使用运行时多态性。 Of course you have to actually implement the functions you want in the CCmdBase class.当然,您必须在CCmdBase类中实际实现您想要的功能。 You can have template functions inside a non-template class definition, eg:您可以在非模板类定义中使用模板函数,例如:

struct CCmdBase
{
    template<typename T> T getValue()
    {
         return dynamic_cast< CCmd<T> & >(*this).getValue();
    }

    virtual ~CCmdBase() {}
 };

As this question was recently tagged as the 'duplicate' of a new question, is should be added that since C++17 we have std::any由于这个问题最近被标记为新问题的“重复”,因此应该补充说,自 C++17 以来,我们有std::any

The class std::any describes a type-safe container for single values of any type.std::any为任何类型的单个值描述了一个类型安全的容器。

and std::variantstd::variant

The class template std::variant represents a type-safe union.类模板std::variant表示类型安全联合。 An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no value.任何给定时间的std::variant实例要么持有其替代类型之一的值,要么在错误的情况下 - 没有值。

as part of the C++ standard.作为 C++ 标准的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM