简体   繁体   中英

STL container with generic/templated variables

I would simply like to do something of the following:

template <typename T>
class gvar {
private:
    T var;
public:
    gvar(T var) : var(var) {}
};

std::stack<gvar> some_stack;

g++ spits out all kinds of errors about how gvar is not a type. Is this achievable in some relatively easy way? I prefer not to use boost::any / boost::variant.

edit:

To clarify on what I want:

An std::stack that can hold variables of different types (just primitives is fine).

Because gvar isn't a type, it's a type template. You need to specify a template argument for it:

std::stack< gvar<int> > some_stack;

You have to either instantiate the template class or approach this in some other way. For example, you can make an std::stack<gvar<int> > , or you could try solutions such as Boost::Any .

您只需指定实例化gvar类型,例如:

std::stack<gvar<int> > some_stack;

In general, if you want polymorphism, you'd use a base class:

class GVarBase
{
public:
  virtual ~GVarBase() {}
};

template <typename T>
class GVar: public GVarBase
{
public:
private:
  T mVar;
};

std::stack< std::unique_ptr<GVarBase> > stack;

Note that with the current code you have, even std::stack< GVar<int> > would not work, a default constructor is required.

If you can suffer with a limited span, that is you know full well the length of the collection you can look at using tuples . Of course, you're also going to need to know the type in advance.

boost::tuple<gvar<double>,gvar<int>,gvar<double> > myItems;

Which in your case would probably be best expressed simply as:

boost::tuple<double,int,double> myItems;

No. There's no way to do what you're trying to do. More clarity on the problem you're trying to solve with this attempt might allow me to provide a workaround.

Seems you need something like this:

class gvar {
        struct base_val { 
                virtual ~base_val() {} 
        };
        template <class T>
        struct con_value : base_val{
                con_value(T val): value(val) {}
                T value; 
        };      
        base_val *var;
public:
        template <typename T>
        gvar(T var) : var(new con_value<T>(var)) {}
        template <typename T>
        T* getValue() { 
                con_value<T> *ptr = dynamic_cast<con_value<T>*>(var);
                if(ptr == NULL) return NULL;
                return &ptr->value;
        }
};

std::stack<gvar> some_stack;

(link to ideone with working example http://www.ideone.com/gVoLh )

This is simplified boost::any , so if you can, just use boost::any instead of this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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