views:

81

answers:

4

I have a class test which isn't standard constructable nor assignable due to certain reasons. However it is copy constructable - on may say it behaves a bit like a reference.

Unfortunately I needed a dynamic array of these elements and realized that vector<test> isn't the right choice because the elements of a vector must be standard constructable and assignable. Fortunately I got around this problem by

  • using vector<T>::reserve and vector<T>::push_back instead of vector<T>::resize and direct filling the entries (no standard construction)
  • the copy'n'swap trick for assignment and the fact that a vector is usually implemented using the Pimpl-idiom (no direct assignment of an existing test element), i.e

    class base {
    private:
        std::vector<test> vect;
        /* ... */
    public:
        /* ... */
        base& operator= (base y) {
            swap(y);
            return *this;
        }
        void swap(base& y) {
            using std::swap;
            swap(vect, y.vect);
        }
       /* ... */
    };
    

Now I assume that I probably didn't considered every tiny bit and above all these tricks are strongly implementation dependent. The standard only guarantees standard behavior for standard constructable and assignable types.

Now what's next? How can I get a dynamic array of test objects?

Remark: I must prefer built in solutions and classes provided by the standard C++.

Edit: I just realized that my tricks actually didn't work. If I define a really* non assignable class I get plenty of errors on my compiler. So the question condenses to the last question: How can I have a dynamic array of these test objects?

(*) My test class provided an assignment operator but this one worked like the assignment to a reference.

A: 

Write your own dynamic array class. Sounds like less work than trying to make the STL one work with that strange type.

Amnon
It sounds like that - nevertheless using something provided by the standard is much safer and less error prone than your own cooked solutions. That's why I'm asking...
phlipsy
This might be quite tricky to get right. I would advice against it.
David Rodríguez - dribeas
@phlipsy The standard library is safer and less error prone _if_ you satisfy its constraints. It's the constraints that help it being correct and robust. If you try to circumvent them, you may think that you succeed partially, but you won't be able to assume the same level of correctness as in the official case.
Daniel Daranas
@Daniel: I agree. That's why I desperately needed a solution to replace my potentially error prone code.
phlipsy
+2  A: 

Consider using Boost's ptr_vector, part of the Boost Pointer Container Library. See in particular advantage #3 in that library's motivation.

ariels
Unfortunately I must prefer the build in solutions because I'm working with other programmers using different compilers on different platforms. Restricting to the bare minimum has priority.
phlipsy
No problem: all built-in containers share the assignable requirement. Hence, you need a non-standard one. Boost is the obvious candidate - almost standard, widely tested, liberal license.
MSalters
Else consider using `shared_ptr` (either boost or TR1) or `reference_wrapper` (again boost or C++0x) if all your compilers support it. Anyway I agree with MSalters, the best you can do is adding boost to the project. Chances are that boost supports all your compilers, while the TR1 or C++0x extensions are not broadly supported.
David Rodríguez - dribeas
Finally I got the problem solved by a simple vector. My test class can directly and fast reconstructed from an copyable and standard constructable object. Thus I stored these objects in my vector. But otherwise I think this solution would be the most obvious one.
phlipsy
A: 

You might want to look at Boost.Intrusive -- although that would mean you would need to change the type of test and where in memory you put the instances of test.

Dean Michael
These intrusive containers are a interesting idea but nevertheless it's a bit oversized for my needs.
phlipsy
A: 

How about using a vector of pointers?

Jonas
Finally I got my problem solved exactly this way. But I have to admit that this doesn't arise from my question itself. I didn't mention that my test objects can be stored elsewhere. Otherwise I always would have to worry about freeing the object after their usage...
phlipsy
Great! There are caveats sure but they could be walked around. If you could you should use a smart pointer of some sort.
Jonas