2
class MyClass
{
    public:
        friend void function(MyClass& mc)
        {
            std::cout << "Friend function from thread" << std::endl;
        }    
        void init()
        {
            thr = std::thread(function, this);
            thr.join();
        }

    private:
        std::thread thr;

};

  int main()
   {
    std::cout << "This is main function" << std::endl;
    MyClass nc;
    nc.init();

    return 0;
   }

Error C2065 'function': undeclared identifier

How to create thread inside a class not using any static function?

Duck Dodgers
  • 3,409
  • 8
  • 29
  • 43
pronob roy
  • 33
  • 2
  • Why are you not doing init in your constructor? I think you need to initialize thread directly in your constructor for it to work – styphNate Feb 21 '19 at 08:11
  • 3
    Possible duplicate of [Start thread with member function](https://stackoverflow.com/questions/10673585/start-thread-with-member-function) – Alan Birtles Feb 21 '19 at 08:14
  • 1
    You forgot ro dereference `this`, but there seem to be more errors. – HolyBlackCat Feb 21 '19 at 08:14
  • 2
    @AlanBirtles How is this a duplicate? Here we have a friend definition, which creates non-member functions. – HolyBlackCat Feb 21 '19 at 08:15
  • @styphNate `std::thread` is not copiable, but movable. You can assign an rvalue at any time to a thread in any state (see [operator=](https://en.cppreference.com/w/cpp/thread/thread/operator=)). – Aconcagua Feb 21 '19 at 08:35
  • @HolyBlackCat Not a true duplicate - but still showing a possible way to avoid *static* functions... – Aconcagua Feb 21 '19 at 08:41
  • @HolyBlackCat I hadn't noticed the friend function, I guess the OP only did that because they didn't know how to call a member function from a `std::thread`, I can't see why else you'd try to declare a friend function for a class inside a class – Alan Birtles Feb 21 '19 at 09:47

2 Answers2

4

I do not know why the lookup of your friend function does not work in this context, maybe someone else knows.
But the fastest way to archive what you want is either a lamdba or declare your function.
E.g.

class MyClass;
void function(MyClass& mc);
class MyClass
{
public:
    friend void function(MyClass& mc)
    ...
    void init()
    {
        // either do this
        thr = std::thread([this](){function(*this);});
        // or this note the std::ref. You are passing a reference. Otherwise there will be a copy
        thr = std::thread(&function, std::ref(*this));
        thr.join();
    }

private:
    std::thread thr;

};
....
mkaes
  • 13,781
  • 10
  • 52
  • 72
  • It's perfectly fine to pass a pointer by value, instead of a `std::ref` to a dereferenced pointer. – super Feb 21 '19 at 08:42
  • @super ["compiler says no"](https://godbolt.org/z/nZMZHA). or how did you mean it? – Mike van Dyke Feb 21 '19 at 08:47
  • @super I don't think so. The `function` accepts a reference and not a pointer. So passing the pointer by value won't work here. Another solution would be to change `function` to accept a `MyClass*` then the pointer by value would be fine. – mkaes Feb 21 '19 at 08:47
  • Right, missed the whole friend function. Too early. – super Feb 21 '19 at 08:50
0

Well @mkaes beat me to the answer, but I had slightly modified your function() to accept a pointer to the class and not a reference.

  • You cannot access a friend function inside a class like you can access other member functions.

    1. The problem was that your friend function had no global declaration even though, you were declaring it as a friend function in the class.
    2. So we define the function outside the class and leave a friend declaration inside.
    3. Now since the function() doesn't know about the class MyClass, we have to forward declare the MyClass class also.

code:

#include <iostream>
#include <thread>

class MyClass;

void function(MyClass* mc)
{
    std::cout << "Friend function from thread" << std::endl;
}

class MyClass
{
public:
    void init()
    {
       thr = std::thread(function, this);
       thr.join();
        // function(this);
    }
    friend void function(MyClass* mc);
private:
    std::thread thr;

};

int main()
{
    std::cout << "This is main function" << std::endl;
    MyClass nc;
    nc.init();

    return 0;
}

Output:

This is main function
Friend function from thread

EDIT:

As per the discussion in the comments, my first code posted here had the problem that you could not call a member function or access a member variable inside the friend function(), since the class was defined afterwards. To address that here is the alternative below. But anyways, @mkaes has already answered it in this way from the beginning.

#include <iostream>
#include <thread>

class MyClass;
void function(MyClass* mc);

class MyClass
{
public:
    void init()
    {
       thr = std::thread(function, this);
       thr.join();
        // function(this);
    }
    friend void function(MyClass* mc)
    {
        std::cout << "Friend function from thread" << std::endl;
        mc->test();
    }
    int test(){}
private:
    std::thread thr;

};



int main()
{
    std::cout << "This is main function" << std::endl;
    MyClass nc;
    nc.init();

    return 0;
}
Duck Dodgers
  • 3,409
  • 8
  • 29
  • 43
  • *'And you cannot access a friend function inside a class like you can access other member functions.'* - the 'why' would be the most interesting point about. Any reference to the standard? – Aconcagua Feb 21 '19 at 09:00
  • @Aconcagua, my point was **NOT like other member functions** *(other than that you can do it, like in the above code, for example `:)` )*. I don't have a reference to the standard, but I guess that it has something to do with the *friend* function no relationship to *this*, like static functions. – Duck Dodgers Feb 21 '19 at 09:05
  • 1
    Hm, I recall something like inlined member functions being compiled as if being defined right after the class - so that they can see the complete class definition and access members no matter if declared after or before the function. Suppose the same applies for the inline friends as well, apparently (unfortunately) placing the definition after the member definitions (instead of e. g. in between class and members)... – Aconcagua Feb 21 '19 at 10:09
  • Ah ok. Good to know. Thanks for sharing that @Aconcagua. `:)` – Duck Dodgers Feb 21 '19 at 11:03
  • Thank's for your reply. can you please tell me if i can call member function inside thread then how? I am using VS2017 as IDE – pronob roy Feb 21 '19 at 11:46
  • @pronobroy, yes, you can. But for that the code needs to be changed a bit. The function definition would have to moved to after the class definition *(or even inside the class)*. And the place where the function has been defined, needs to be replaced with the function declaration. – Duck Dodgers Feb 21 '19 at 11:57
  • @pronobroy, I edited my answer. But as you can see mkaes, has already answered this correctly from the beginning. – Duck Dodgers Feb 21 '19 at 12:01
  • @pronobroy, best to keep `class definition` in a `header file` (containing the declarations only *hopefully*) and `class implementation` in separate `source file`, so that you don't bump into such problems anyways. – Duck Dodgers Feb 21 '19 at 15:59