Multithreading with class template function

So, I'm pretty new to the parallel C ++ 11 programming features provided by the STL, and I've been playing around with the following code:

    #include <iostream>
    #include <thread>
    #include <mutex>
    #include <list>

    using namespace std;

    template <typename T>
    class Container
    {
        private:
            mutex mu;
            list<T> myList;

        public:
            void add(T element)
            {
                lock_guard<mutex> lock1(mu);
                myList.emplace_back(element);
            }
            void remove()
            {
                lock_guard<mutex>lock2(mu);
                myList.pop_back();
            }
            void print()
            {
                for(const auto & element : myList)
                {
                    cout << element << endl;
                }
            }
    };

    int main()
    {
        Container<int> c;

        thread t1(&Container<int>::add, c, 5); //ERROR
        thread t2(&Container<int>::add, c, 10); //ERROR

        thread t4(&Container<int>::remove, c); //ERROR
        thread t5(&Container<int>::remove, c); //ERROR

        t1.join();
        t2.join();
        t4.join();
        t5.join();

        c.print();
    }

      

When I try to compile my code, the lines marked as "ERROR" made the compiler tell me:

error: call to implicitly-deleted copy constructor of
  'typename decay<Container<int> &>::type' (aka 'Container<int>')
return _VSTD::forward<_Tp>(__t);

error: no matching constructor for initialization of
  '__tuple_leaf<1UL, Container<int> >'
        __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,

error: no matching function for call to '__decay_copy'
                            __decay_copy(_VSTD::forward<_Args>(__args))...));
                            ^~~~~~~~~~~~

      

Now I have looked at this question and this question when writing the code, but I am still missing some small details. If someone can provide some help, that would be great. Thank!

+3


source to share


1 answer


A thread

must make a copy of all its arguments, and yours Container

cannot be copied. It is not copied because one of its members ( std::mutex

) is not copied. The solution to this question, rather than to give thread

c

, is to give it something that it can do.

I.e:

    thread t1(&Container<int>::add, &c, 5);

      



The following should work, but cannot (see TC's comment ):

    thread t2(&Container<int>::add, std::ref(c), 10);

      

Note that it's a good thing this didn't compile for you, because otherwise your threads will be doing work on different copies of your container, not just what you probably expect.

+2


source







All Articles