Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using vectors with classes that contain non-copyable data types

Tags:

c++

stdvector

My issue is that I have a class which contains a std::ifstream, std::ofstream, and std::mutex. None of these objects can be directly copied as shown in the example below.

std::ifstream stream1;
std::ifstream stream2;
stream1 = stream2; //<-Compiler Error!

My problem is not that I want to copy any instances of my class, but that the push_back() function in vectors is trying to call the copy constructor for my class. I have designed an example that replicates my issue and pasted it below.

#include <fstream> //for std::ifstream // std::ofstream
#include <vector> //for std::vector
#include <mutex> //for std::mutex

class MyClass
{
public:
    MyClass(int ID) : ID(ID) { }
    std::ofstream outputstream;
    std::ifstream inputstream;
    std::mutex mymutex;
private:
    int ID;
};

int main()
{
    std::vector<MyClass> MyVector;
    MyVector.push_back(MyClass(1)); //<-- Error C2280 'MyClass::MyClass(const MyClass &)': attempting to reference a deleted function

    return 0;
}

I am having issues trying to figure out how to get around this error. Any help would be greatly appreciated. Keep in mind, I will never be directly calling the copy constructor as I have no need in my actual scenario to ever copy an instance of this class, but it seems that push_back is calling it and I have been unsuccessful in my attempts to override it.

Edit: I think one way to fix it would be to use pointers instead of ifstream,ofstream, and mutex objects but I would prefer to avoid this at all costs.

like image 863
user2980207 Avatar asked Sep 20 '16 02:09

user2980207


People also ask

Can vectors hold different data types?

A vector will hold an object of a single type, and only a single type.

Does vector automatically deallocate memory?

If you declare a std::vector in a specific scope, when that scope is no longer valid the std::vector memory will be destructed and freed automatically. Strategies like SBRM reduce the chance of introducing memory leaks. In summary: std::vector simplifies much of the overhead code required to manage dynamic arrays.

Are vectors trivially copyable?

It does not have internal pointers and can therefore be copied simply by using memcpy . It therefore is trivial to copy.

Can you memcpy into a vector?

You can use the Use memcpy for vector assignment parameter to optimize generated code for vector assignments by replacing for loops with memcpy function calls. The memcpy function is more efficient than for -loop controlled element assignment for large data sets. This optimization improves execution speed.


1 Answers

The real problem here is that this class contains a std::mutex member. Which cannot be copied/moved. This means that classes that have mutex members don't like to live inside vectors.

You need a custom copy and/or move constructors, for your class, and implement the appropriate semantics to copy the streams, and figure out what you want to do with the mutex.

like image 199
Sam Varshavchik Avatar answered Sep 25 '22 05:09

Sam Varshavchik