【问题标题】:Function call is giving me the error expression must have class type函数调用给了我错误表达式必须有类类型
【发布时间】:2014-05-30 20:42:28
【问题描述】:

我做了一个简单的函数调用,它显示了一个我有值的列表的内容。这是函数定义:

void display_list(list<string>*type_list)
{
    cout << "You made a function call" << endl;
    for (list<string>::iterator dis = type_list.begin(); dis != type_list.end(); ++dis)
    {
        cout << *dis;
        cout << "\n";
    }
}

所有这一切都应该让我更轻松,因为在我的代码中有很多次我必须显示列表的内容,所以我试图让自己更轻松并调用函数所以我要做的就是调用函数:

display_list(&list_name_here);

虽然一切正常,但正如您所见,我添加了一个测试“cout”以确保函数调用正常工作,但它不显示内容,并且我收到一个突出显示的错误

type_list

然后弹出错误,说表达式必须具有类类型?

现在我确实将代码更改为如下所示:

   void display_list(list<string>*type_list)
{
    cout << "You made a function call" << endl;
    list<string> gen;
    *type_list = gen;

    for (list<string>::iterator dis = gen.begin(); dis != gen.end(); ++dis)
    {
        cout << *dis;
        cout << "\n";
    }
}

在这种形式中,我将 type_list 取消引用到一个局部变量中,然后照常进行。由于此方法确实消除了类类型错误,但是当我编译并运行它时,列表中没有显示任何内容。 list 真的很简单,所以它应该只显示 10 个值。

现在,如果您要问,将原始算法放在我的主代码中并且我用适当的列表名称替换 type_list 时,代码可以完美地工作并设计。显示列表的内容。所以我知道我的错误不在其中。

任何人都可以对此有所了解吗?

【问题讨论】:

    标签: c++ list pointers iterator


    【解决方案1】:

    您需要使用-&gt; 从指针访问成员和成员函数。

    void display_list(list<string>*type_list)
    {
        cout << "You made a function call" << endl;
        for (list<string>::iterator dis = type_list->begin(); dis != type_list->end(); ++dis)
        {
            cout << *dis;
            cout << "\n";
        }
    }
    

    至于你第二次尝试空列表的问题,

    list<string> gen;
    *type_list = gen;
    

    将*type_list 设置为gen,但不会更改gen。 gen 是一个空列表,您继续对其进行迭代。

    你可以使用:

    list<string> gen = *typ_list;
    

    或者(感谢@MattMcNabb)

    list<string>& gen = *typ_list;
    

    【讨论】:

    • 或list&lt;string&gt; &amp;gen = *typ_list;
    【解决方案2】:

    行内:

    *type_list = gen;
    

    您将type_list 更改为指向gen。请注意,此时gen 为空。 此外,稍后您在 for 循环中使用来自 gen 的迭代器,尽管其中没有任何内容。

    你可能想读那一行:

    gen = *type_list;
    

    gen 是不必要的,你可以直接从type_list 获取迭代器。

    【讨论】:

      【解决方案3】:

      我很困惑。你的函数display_list 并没有真正做任何事情。

      这是我对你的功能的检查。

      通过 const 引用传递
      大型数据结构应通过常量引用传递,除非您打算对其进行修改。显示函数不应修改其参数:

      曾是:
      void display_list(list&lt;string&gt;*type_list)
      改为:
      void display_list(const list&lt;string&gt;&amp; type_list)

      复制空列表会删除现有列表
      此行创建一个名为 gen 的空列表。
      list&lt;string&gt; gen;

      这一行将空列表复制到传递的列表中:
      *type_list = gen;

      迭代一个空列表没有任何功能
      由于 gen 列表是空的,因为您是新创建的,因此此循环没有任何功能。

      for (list<string>::iterator dis = gen.begin(); dis != gen.end(); ++dis)
      {
          cout << *dis;
          cout << "\n";
      }
      

      你想做什么?

      你真的需要在打印之前复制一个列表吗?
      (无缘无故复制一个列表是在浪费数据和执行时间。)

      为什么要修改您传递的列表?

      我很困惑。

      编辑 1:
      显示列表的代码:

      void display_list(const std::list<string>& type_list)
      {
        std::list::const_iterator iter;
        for (iter =  type_list.begin();
             iter != type_list.end();
           ++iter)
        {
          std::cout << *iter << "\n";
        }
      }
      

      请参阅:无需创建新列表或复制旧列表。

      该函数不修改列表,基于参数列表中的const 并使用const_iterator。

      由于列表是通过引用传递的,所以没有指针,也没有解引用问题。

      【讨论】:

        【解决方案4】:

        . 运算符仅用于对象。要在您指向的对象上查找成员,请编写 (*ptr).name 或等效的 ptr-&gt;name。

        例子:

        string s;
        string *ptr = &s;
        
        cout << s.size() << "\n";
        cout << ptr->size() << "\n";
        

        话虽如此,更好的解决方法是通过引用传递列表,而不是通过指针传递:

        void display_list(list<string> &type_list)
        

        然后你使用. 语法。

        最好是通过 const 引用传递;那么你也可以使用const_iterator。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-07
          • 1970-01-01
          • 1970-01-01
          • 2018-03-27
          相关资源
          最近更新 更多