【问题标题】:STL container with generic/templated variables具有通用/模板变量的 STL 容器
【发布时间】:2011-06-17 15:22:27
【问题描述】:

我只想做以下事情:

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

std::stack<gvar> some_stack;

g++ 吐出各种关于 gvar 不是类型的错误。这可以通过某种相对简单的方式实现吗?我不喜欢使用 boost::any / boost::variant。

编辑:

澄清我想要什么:

一个 std::stack 可以保存不同类型的变量(只是原语就可以了)。

【问题讨论】:

  • 为什么不使用 boost::any?它专为您所追求的目标而设计(尽管您的问题非常模糊,因此很难确定)——无论如何,您永远不会解释您希望代码做什么。我们无法从您编造的语法中猜出您希望它如何工作。您是否希望能够创建一个std::stack,它可以容纳具有多种不同类型Tgvars?像 gvar&lt;int&gt;gvar&lt;float&gt; 在同一个堆栈中吗?
  • @jalf:实际上只是在同一个堆栈中的 'int' 和 'float' 就可以了......我试图用模板做一些事情,但后来我发现不能那样工作。
  • 我们想知道union 不符合您的目的的原因。

标签: c++ templates generics variables stack


【解决方案1】:

因为gvar 不是类型,它是类型模板。你需要为它指定一个模板参数:

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

【讨论】:

  • 以 2 秒的优势击败我! ;)
  • 就是这样,我-不想-指定它。类型只会在运行时知道,我刚刚意识到模板不能那样工作......有什么建议吗?
  • @Daniel:您可以先将该信息添加到您的问题中。 ;)
  • 模板必须在运行时完全解析。如果您需要仅在运行时知道的类型,这将取决于您需要做什么,但您可能需要一个抽象基类和继承的实现。
【解决方案2】:

您必须实例化模板类或以其他方式处理它。例如,您可以创建std::stack&lt;gvar&lt;int&gt; &gt;,也可以尝试Boost::Any 等解决方案。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      如果您可以忍受有限的跨度,那就是您完全了解使用tuples 可以查看的集合的长度。当然,您还需要提前知道类型。

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

      在您的情况下,最好简单地表达为:

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

      【讨论】:

        【解决方案5】:

        没有。没有办法做你想做的事。更清楚您尝试通过此尝试解决的问题可能允许我提供解决方法。

        【讨论】:

          【解决方案6】:

          一般来说,如果你想要多态,你会使用一个基类:

          class GVarBase
          {
          public:
            virtual ~GVarBase() {}
          };
          
          template <typename T>
          class GVar: public GVarBase
          {
          public:
          private:
            T mVar;
          };
          
          std::stack< std::unique_ptr<GVarBase> > stack;
          

          请注意,使用您当前的代码,即使std::stack&lt; GVar&lt;int&gt; &gt; 也不起作用,需要默认构造函数。

          【讨论】:

          • 使用多态性,存储指针而不是对象将是一个真正的好主意。 ;)
          • @jalf:不是吗? /我很困惑
          • unique_ptr 一直都在吗?我想我当时应该多加注意。 ;)
          • 好的,谢谢!这就是我钓鱼的目的。最终使基类成为纯虚拟并在我的子类中重载了几个运算符。
          【解决方案7】:

          看来你需要这样的东西:

          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;
          

          (链接到带有工作示例的 ideone http://www.ideone.com/gVoLh

          这是简化的boost::any,所以如果可以的话,只需使用boost::any 代替这个。

          【讨论】:

          • 有点泄漏,但应该使用boost:shared_ptr 而不是普通指针。如果你已经使用 boost,你可以使用 boost::variantboost::any
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-22
          • 2019-04-03
          • 1970-01-01
          • 1970-01-01
          • 2014-09-10
          • 2019-04-30
          相关资源
          最近更新 更多