简体   繁体   中英

Function call is giving me the error expression must have class type

I have made a function call that in simple terms, displays the content of a list that i have values for. Here is the function definition:

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

All this is supposed to do is make it easier on me, because there are numerous times throughout my code that i have to display the contents of a list, so i tried to make it easier on myself and make a function call for it so all i have to do is make the function call:

display_list(&list_name_here);

although everything works fine, as you can see i added a test 'cout' to make sure the function call works correctly, but it doesn't display the contents, and i get an error that highlights the

type_list

and error pops up that says expression must have class type?

Now I did change the code to look like this:

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

In this form i dereferenced type_list into a local variable, and then proceeded as normal.. As this method does get rid of the class type error, but when i compile and run it, nothing get displayed from the list.. The list is really simple so it should only display like 10 values.

Now in case you are asking, that original algorithm when placed in my main code and i replace the type_list with the appropriate list names, the code then works perfectly and designed. To display the contents of the list. So i know my error isn't in that.

Can anyone please shed some light on this?

You need to use the -> to access members and member functions from a pointer.

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

As for the problem of an empty list in your second attempt,

list<string> gen;
*type_list = gen;

sets *type_list to gen but it doesn't change gen . gen is an empty list and you proceed to iterate on it.

You could have used:

list<string> gen = *typ_list;

or (thanks, @MattMcNabb)

list<string>& gen = *typ_list;

In the line:

*type_list = gen;

you are changing type_list to point to gen . Note that gen is empty at this point. Also, later you use an iterator from gen in the for loop, despite nothing being in it.

You might have meant that line to read:

gen = *type_list;

gen is unnecessary though, you can just get an iterator from type_list directly.

I'm confused. Your function display_list doesn't really do anything.

Here's my inspection of your function.

Pass by const reference
Large data structures should be passed by constant reference, unless you plan to modify it. A display function should not be modifying its argument:

Was:
void display_list(list<string>*type_list)
Change to:
void display_list(const list<string>& type_list)

Copying an empty list deletes the existing list
This line creates an empty list called gen .
list<string> gen;

This line copies the empty list to the list passed:
*type_list = gen;

Iterating an empty list has no functionality
Since the gen list is empty because you newly created it, this loop doesn't have any functionality.

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

What are you trying to do?

Do you really need to copy a list before printing it?
(Copying a list for no reason is a waste of data and execution time.)

Why are modifying the list you passed?

I'm confused.

Edit 1:
The code to display a list:

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

See: no need to create a new list or copy the old list.

The function doesn't modify the list, based on the const in the parameter list and using the const_iterator .

Since the list is passed by reference, no pointers, no dereferencing issues.

The . operator is only for using on objects. To look up members on an object that you are pointing to, either write (*ptr).name , or equivalently ptr->name .

Example:

string s;
string *ptr = &s;

cout << s.size() << "\n";
cout << ptr->size() << "\n";

Having said that, a better fix would be for you to pass your list by reference, instead of passing by pointer:

void display_list(list<string> &type_list)

Then you use the . syntax.

Even better would be to pass by const reference; then you use const_iterator also.

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