-1

So I am using a custom vector container from: https://github.com/patr0nus/Vector/blob/master/Vector.h

and I am trying to create a vector of unique_ptr's pointing to a custom Class object.

It used to fail with:

error: object of type 'std::__1::unique_ptr std::__1::default_delete>' cannot be assigned because its copy assignment operator is implicitly deleted

I fixed it by adding the following code to vector.h:

void push_back(T&& val)
    {
        resize(m_size + 1);
        m_container[m_size - 1] = std::move(val);
    }

Now, the problem is, I am unable to iterate over this vector and other functions like swap are failing:

no matching function for call to 'swap'
        swap(*__x4, *__x5);
candidate template ignored: could not match 'tuple' against 'unique_ptr'
swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)

I need some guidance on how to fix these issues.

  • This vector seems to be designed for use with POD types only. – Baum mit Augen Oct 03 '16 at 20:56
  • 9
    Use `std::vector` is the solution. Why do you need this custom one in the first place? The problem with the implementation is that it absolutely requires `T` to be CopyConstructible, when `std::unique_ptr` very much isn't. – AndyG Oct 03 '16 at 20:56
  • 3
    Um.....Why not just use std::vector? – mascoj Oct 03 '16 at 20:56
  • 1
    Please provide a [mcve]. – Barry Oct 03 '16 at 20:57
  • @Barry, You can very easily download the code from Git, and write a few extra lines of code to create a new vector of unique_ptr's pointing to a primitive type and try messing around with it. If I were to paste my code, it would make this thread very long and time consuming to copy paste. – SomeAndroidProgrammar Oct 03 '16 at 21:00
  • @AndyG I am trying to learn and improve this existing implementation. – SomeAndroidProgrammar Oct 03 '16 at 21:01
  • 8
    @SomeAndroidProgrammar It's not up to *me* to make a minimal, complete, and verifiable example. It's up to you. – Barry Oct 03 '16 at 21:03
  • @SomeAndroidProgrammar you don't need (and aren't supposed) to paste all of your code. Create a mcve, as described in the link. – eerorika Oct 03 '16 at 21:04
  • @some: you'll probably gain more by studying an implementation of `std::vector` than some other vector. You've already learnt as much is likely to be useful here; if you want to fix it, then that's laudable, but you'll really need to make the effort to reduce to a MCVE. That's likely to be a small effort in comparison to the overall task, and educational in itself. – Toby Speight Oct 03 '16 at 21:08
  • Very related: http://stackoverflow.com/a/38807554/2752075 – HolyBlackCat Oct 03 '16 at 21:58

3 Answers3

5

You can't use patr0nus/Vector with non POD types. The reason is quite simple: it uses memcpy at many places, and require the types to be copy constructibe.

Using it with anything else that is not POD is actually undefined behaviour. Don't use that vector for non POD types. There's no way around it.

As you might know, you can use a well defined implementation that respect a precise set of requirement and is probably more optimized than that vector implementation: std::vector.

If you have some memory or allocation constraints, you may implement a custom allocator.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
1

To add to the answer given, since your vector class only works with POD types, the way you can ensure that you are working with POD types only is to use the std::is_pod function along with static_assert. Using these C++ facilities will disallow programs from being created that violate the POD requirements.

When you construct the vector, you can make the tests in those functions:

#include <algorithm>
//...
template<typename T>
class Vector
{
   Vector(int initialSize = 1)
   {
      static_assert(std::is_pod<T>(), "Sorry, only POD types are allowed");
     //...
   }

    Vector(const Vector &source)
    {
      static_assert(std::is_pod<T>(), "Sorry, only POD types are allowed");
      //...
    }
    //...
};

This ensures that if anyone were to do something like this:

Vector<std::string> sV;

A compiler error will show up instead of the code compiling and causing the problems that you're seeing now.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • `is_pod` is convertible to bool, so just `static_assert(std::is_pod{}, "blah")` is appropriate. Also, you could assert this once at the top of the class. :) – GManNickG Oct 04 '16 at 00:16
0

In resize() function you have:

{
...
            m_capacity = size * 2;//The new capacity is double of the size.
            T* oldPtr = m_container;
            m_container = (T*)malloc(m_capacity * sizeof(T));//Allocate the new container.
            memcpy(m_container, oldPtr, m_size * sizeof(T));//Copy the elements.
            destory(oldPtr, m_size);//Destory the old container.
            free(oldPtr);
...
}

So you need to put POD (plain old data) elements to you vector:
What are POD types in C++?

Community
  • 1
  • 1
M. S.
  • 109
  • 7