【问题标题】:Accessing variables in a template that is a vector of a custom data type with multiple variables访问模板中的变量,该模板是具有多个变量的自定义数据类型的向量
【发布时间】:2013-04-11 12:47:53
【问题描述】:

如何在increment 函数中访问变量itemtypetotal?我下面的代码给了我如下错误

Counter2.h:在成员函数'int Counter::increment(T)'中:

Counter2.h:28:31: 错误:“itemtype”未在此范围内声明

Counter2.h:36:22: 错误:“itemtype”未在此范围内声明

Counter2.h:36:39: 错误:'total' 未在此范围内声明

我必须能够使用命令Counter<T> counter;,其中T可以是任何类型,例如字符串和counter.increment()

#include<string>
//#include<cstdlib>
#include<vector>

using std::vector;
using std::string;

template<class T>
class Record{
   public:
      T itemtype;
      int total;   
};

template<class T>
class Counter{
      vector< Record<T> > data;
   public:
      int increment(T item);
      int count(T item);
      void printSummary();
};

template<class T>
int Counter <T> :: increment(T item){
   bool check = false;

   for(int i=0; i < data.size(itemtype); i++){
      if(data[i].itemtype == item){
         data[i].total++;
         bool check = true;
         break;
      }
   }
   if(check == false){
      data.push_back(itemtype = item, total = 1);
   }
}

int main(){

   Counter<string> counter;   

   counter.increment("orange");
   counter.increment("orange");

   return 0;
}

【问题讨论】:

    标签: c++ function templates vector stl


    【解决方案1】:

    在线for(int i=0; i &lt; data.size(itemtype); i++){

    将是:for(int i=0; i &lt; data.size(); i++){

    data.push_back(itemtype = item, total = 1); 可以是:

    1. data.push_back({item, 1}); // by using initializer list ; C++11

    2. 或者,

      Record r; 
      r.itemtype = item; 
      r.total = 1;
      data.push_back(r);
      

    你可以看看:http://www.cplusplus.com/reference/vector/vector/ 了解 std::vector。

    【讨论】:

    • 非常感谢,只是出于兴趣,您使用 c++ 工作了多长时间?
    • 可能在 1 到 2 年之间。
    • hu-ju,但你忽略了你的导师是 Bjarne Stroustrup 教授这一“无关紧要”的事实。这是真的吗?
    • 确实如此。你怎么知道的?
    • 恭喜!太棒了 :-) 这就是 http 的意义所在:点击链接。所以-您的个人资料-您的网站。他也是我的“讲师”……但我认为是从 1990 年开始的书籍,以及带注释的 c++ 参考手册左右。尽管如此,我认为让 Record 成员公开并不是一个大主意。
    【解决方案2】:

    我不太确定我是否理解您在这里的目的,但首先您尝试访问 Record 类的私有成员。您可以记录一个结构(默认为公共),或提供 getter/setter 或添加:

    friend class Counter;
    

    记录以便 Counter 可以访问其私有成员。

    【讨论】:

    • 我有这些错误但我不知道它们是什么意思Counter2.h:26:4: error: ‘class std::vector&lt;Record&lt;std::basic_string&lt;char&gt; &gt;, std::allocator&lt;Record&lt;std::basic_string&lt;char&gt; &gt; &gt; &gt;’ has no member named ‘count’ Counter2.h:26:4: error: ‘class std::vector&lt;Record&lt;std::basic_string&lt;char&gt; &gt;, std::allocator&lt;Record&lt;std::basic_string&lt;char&gt; &gt; &gt; &gt;’ has no member named ‘itemtype’ Counter2.h:27:7: error: ‘class std::vector&lt;Record&lt;std::basic_string&lt;char&gt; &gt;, std::allocator&lt;Record&lt;std::basic_string&lt;char&gt; &gt; &gt; &gt;’ has no member named ‘itemtype’
    • vector类基本上没有count方法,也没有itemtype字段。因此,为什么我说我不确定你在追求什么。
    • 谢谢,我没有意识到 count() 不是向量的方法,并且已经更改了示例,但我仍然遇到与访问变量 $ g++ Counter2.h -o Counter2 Counter2.h 相关的错误:在成员函数'int Counter::increment(T)'中:Counter2.h:28:31:错误:'itemtype'未在此范围内声明 Counter2.h:36:22:错误:'itemtype'是未在此范围内声明 Counter2.h:36:39: 错误:“总计”未在此范围内声明
    • 那是因为您没有要推送到向量的封闭 Record 对象。我建议在 Record 中创建一个构造函数: Record(T itemtype, int total) { this->itemtype = itemtype;这->总计=总计;然后你可以这样做:data.push_back(Record(item, 1));
    【解决方案3】:

    您可以在Counter 中将Record 设为私有结构。这不会暴露它的实现。您还需要更改访问data 的方式。它是Recordvector,而不是Record。比如:

    template<class T>
    class Counter
    {
        struct Record{   T itemtype;    int total;      };
        vector< Record > data;
       public:
          int increment(const T& item);
          int count(const T& item);
          void printSummary();
    };
    template<class T>
    int Counter <T> :: increment(const T& item)
    {
       auto i=data.begin();
       i= find(i,data.end(),[&item](const Record& r)
                            {return item==r.itemtype;});
       if (i!=data.end())
           return ++(i->total);
       data.push_back({item, 1}); 
       return 1; 
     }
    

    如果你不喜欢 lambda 的乐趣:

    template<class T>
    int Counter <T> :: increment(const T& item)
    {
        for(int i=0; i < data.size(); ++i)
          if(data[i].itemtype == item)
             return ++(data[i].total);
        data.push_back({item, 1}); 
        return 1;
    }
    

    但我认为您真正需要的是multiset(如果您不关心订单)。像这样的:

    template<class T>
    class Counter
    {
        std::multiset <T> data;
       public:
          int increment(T item);
          int count(T item);
          void printSummary();
    };
    
    template<class T>
    int Counter <T> :: increment(T item)
    {
       data.insert(item);
       return data.count(item);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多