Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: use of deleted function ‘test::test (const test&) C++ in combination with a vector

Tags:

c++

c++11

I have an issue I don't understand. I have a class that spawns a thread. All OK. I make a new object - All OK. If I store these in a vector to iterate through my code fails to compile. I use g++ 4.9 i686. I made the following short program that exactly mimics the problem as the real code is fairly extensive. If someone could clarify or hand me a solution that would be great for my pet project as I'm stuck with this. Code below:

#include <thread>
#include <string>
#include <iostream>
#include <vector>

class test
{
public:
    test();
    void setstring(std::string s);
    ~test() { }
    void runThread() { m_thread = std::thread(&test::print, this); }
    void stop() {on=false;m_thread.join(); }
private:
    std::string s;
    bool on=false;
    std::string m_data;
    std::thread m_thread;
    void print();
};

test::test(){s="";m_data="";}

void test:: print() { std::cout << "I'm running" << '\n'; on = true;
    while(on==true){std::cout << m_data << '\n';}
}

void test:: setstring(std::string s){m_data = s;}

int main()
{
//this works
test one ;
one.setstring("thread running");
one.runThread();
getchar();
one.stop();
std::cout << "I've stopped" << '\n';

std::vector<test> testvec;
test *tst;
tst= new test;
//testvec.push_back(*tst);   //FAILES TO COMPILE
delete tst;
}
like image 918
ZoOl007 Avatar asked Jan 07 '23 23:01

ZoOl007


2 Answers

The version of std::vector::push_back you are using requires a copyable object and your class is not copyable. The reason for that is that std::thread is non copyable

thread(const thread&) = delete;

Since it is non copyable the default copy constructor for your class gets deleted.

To add a default test to testvec you can use std::vector::emplace_back

testvec.emplace_back();

or by constructing a temporary in in the call to push_back

testvec.push_back(test());

Which will call the r-value reference overload of push_back()

You also need to get rid of the constructor and destructor as they prevent the auto creation of the move constructor that you class needs to work correctly. A rule of thumb is that if your class only contains POD types or POD like types(objects that take care of themselves) then you do not need to create any constructors as the ones provided by the compiler will work.

like image 117
NathanOliver Avatar answered Jan 19 '23 00:01

NathanOliver


As others have said, push_back requires the object to be copyable, however you can use std::move to move the thread into the vector, avoiding the copy.

testvec.push_back(std::move(*tst));
like image 27
Czipperz Avatar answered Jan 18 '23 23:01

Czipperz