0

I am trying to do a threaded application to infinitely print a set of numbers after enqueing them. I get this error:

Error 1 error C3867: 'Test::ThreadFunc': function call missing argument list; use '&Test::ThreadFunc' to create a pointer to member.

What am I doing wrong? What is the mistake ?

#include "stdafx.h"

#include <chrono>
#include <mutex>
#include <thread>
#include <list>

class Test {
    std::list<int> queue;
    std::mutex m;

public:
    void ThreadFunc()
    {
        // Loop is required, otherwise thread will exit
        for (;;)
        {
            bool read = false;
            int value;
            {
                std::lock_guard<std::mutex> lock(m);

                if (queue.size())
                {
                    value = queue.front();
                    read = true;
                    queue.pop_back();
                }
            }

            if (read)
            {
                // send(header.data(), header.dataSize());
                // send(proto.data(), proto.dataSize());
                printf("Hello %d\n", value);
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    }

    void TestFunc()
    {
        std::thread thread(ThreadFunc);
        thread.detach();

        int i = 0;
        // Loops only as a test example
        for (;;)
        {
            std::lock_guard<std::mutex> lock(m);
            std::this_thread::sleep_for(std::chrono::milliseconds(2000));
            queue.push_back(i++);
            // Queue Message(header, payload);
        }
    }

};

int main()
{
    Test test;
    test.TestFunc();
}
Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79
chrisrhyno2003
  • 3,906
  • 8
  • 53
  • 102
  • 3
    The error message explains the issue exactly and even tells you what to change in the code. – David Schwartz Jul 26 '15 at 23:34
  • I changed the statement - std::thread thread(ThreadFunc) to std::thread thread(&Test::ThreadFunc); It then gives me an error saying : Error 1 error C2064: term does not evaluate to a function taking 0 arguments – chrisrhyno2003 Jul 26 '15 at 23:35
  • Right. You can only invoke `ThreadFunc` on an instance of the class it belongs to since it's a member function. What are you trying to do? Why is `ThreadFunc` a member of class `Test`? What are you trying to do? – David Schwartz Jul 26 '15 at 23:37
  • Well, I am invoking it from a member function. wouldn't it pass the this pointer implicitly ? – chrisrhyno2003 Jul 26 '15 at 23:38
  • I am trying to print infinite numbers. That's it. If I need to take ThreadFunc() out of the class, I can do that. Would that work ? What's the reason that ThreadFunc cannot be a member function ? – chrisrhyno2003 Jul 26 '15 at 23:39
  • No, it won't pass it implicitly. You can use `std::bind`. – David Schwartz Jul 26 '15 at 23:41

3 Answers3

1

You're attempting to pass a pointer to a member function of a class. When you do this, there's an argument added to the function, tacitly, that is a pointer to the instance of the class that you're invoking the function on. In your case, the pointer to the class will be the this pointer.

See this for syntax reference: Start thread with member function

To answer your comment, why isn't it passed implicitly? You're not calling the function as a member of a class, you're passing the member function by pointer. This is a different, unique, situation, see this reference: Passing a member function as an argument in C++

Also, to save a little future headache, the next problem that comes up is that std::thread's constructor takes its arguments by value, so if you need to pass any arguments by reference, take a look at std::ref.

Community
  • 1
  • 1
mock_blatt
  • 955
  • 5
  • 11
0

Here's the fix. This works. Thank you @mock_blatt

#include "stdafx.h"

#include <chrono>
#include <mutex>
#include <thread>
#include <list>



class Test {
std::list<int> queue;
std::mutex m;

public:
    void ThreadFunc()
    {
        // Loop is required, otherwise thread will exit
        for (;;)
            {
                bool read = false;
                int value;
                {
                    std::lock_guard<std::mutex> lock(m);

                    if (queue.size())
                    {
                        value = queue.front();
                        read = true;
                        queue.pop_back();
                    }
                }

        if (read)
        {
        // send(header.data(), header.dataSize());
        // send(proto.data(), proto.dataSize());
            printf("Hello %d\n", value);
        }

        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}

 void TestFunc()
 {
    std::thread thread(std::bind(&Test::ThreadFunc, this));
    thread.detach();

    int i = 0;
    // Loops only as a test example
    for (;;)
    {
        std::lock_guard<std::mutex> lock(m);
        std::this_thread::sleep_for(std::chrono::milliseconds(2000));
        queue.push_back(i++);
        // Queue Message(header, payload);
    }
}

};

int main()
{
 Test test;
test.TestFunc();
}
chrisrhyno2003
  • 3,906
  • 8
  • 53
  • 102
0

Change std::thread thread(ThreadFunc); to std::thread thread(Test::ThreadFunc, this);

JerryYoung
  • 267
  • 1
  • 3