For your amusement, brought to you by std::vector



  • This gem has been in our code unchanged for quite some time (several years): 

    [code]
    template <typename T>
    class VEC : public std::vector<typename T> {
    public:
    // VEC class does not always work the same as std::vector.
    };
    [/code]
     

    There is historical reason behind this, but even the historical reasons are WTFs, and the code itself has many layers.  A cookie and three points go to any who can list them all.



  • Hmm, it didn't want to keep my brackets.  Oh well.



  • People here complain here about Community Server all the time.  It's really not all that bad, and can be a good choice for many forums.  But here?  On a forum including a large number of programmers?  Community Server sucks for posting code snippets.  There are about 1/2 dozen nice alternatives available for less than the cost of Community Server with a decent method for posting code snippets built in.  So, not your fault about the angle brackets.



  • But then we'd lose these grey shadow guy avatars we've so cleverly photochopped.

     



  • I think there's a problem with something like:

    std::vector<int> *a = new VEC<int>;

    delete a;  // doesn't work correctly now since std::vector doesn't have a virtual destructor

    Excuse me if I've got the syntax wrong, I'm a bit rusty on C++ these days.  I guess the real question is, what would one expect to gain from this?

     




  • @shadowman said:

    I think there's a problem with something like:

    std::vector<int> *a = new VEC<int>;

    delete a;  // doesn't work correctly now since std::vector doesn't have a virtual destructor

    Excuse me if I've got the syntax wrong, I'm a bit rusty on C++ these days.  I guess the real question is, what would one expect to gain from this?

     

    And I do believe the opposite would also fail:

    VEC<int> *a = new std::vector<int>;
     

    The only reason I can think of that someone would do something this hideous is to make sure that all code looks like their code and not using a 3rd party library (granted, STL would be a 1st party, it comes with the language in use). The pain!



  • Both of you are correct; shadowman's delete causes issues at runtime, and JamesKilton's allocation fails at compile-time.

    They did this originally because they wanted to add in a function that would let them shrink the capacity to the size.

    With std::vector, if you have std::vector<int> myvec, myvec.size() <= myvec.capacity(), but myvec.capacity() can be (theoretically) arbitrarily large.  They wanted to provide a way to make the vector reduce the amount of memory used by the vector.  I'm not sure offhand if there is already an easy way to do this or not.  In any case, they made this placeholder class to use instead of std::vector until they could figure out how to make it work... they never did.
     



  • @jcoehoorn said:

    People here complain here about Community Server all the time.  It's really not all that bad, and can be a good choice for many forums.  But here?  On a forum including a large number of programmers?  Community Server sucks for posting code snippets.  There are about 1/2 dozen nice alternatives available for less than the cost of Community Server with a decent method for posting code snippets built in.  So, not your fault about the angle brackets.

    Instead of complaining about the forum, why not try using something like papernapkin, no paste, or pastebin? I'm sure you've probably used one of these before, why not again :).



  • @JamesKilton said:

    And I do believe the opposite would also fail:

    VEC<int> *a = new std::vector<int>;

     

    uhh... maybe I'm being dense because I am halfway drunk, but this type of thing would always fail without some sort of cast.

     And even then you'd be living on the edge.  Are you sure you didn't mean std::vector<int> *a = new VEC<int>; ?  (course, that shouldn't fail).



  • @Heron said:

    Both of you are correct; shadowman's delete causes issues at runtime, and JamesKilton's allocation fails at compile-time.

    They did this originally because they wanted to add in a function that would let them shrink the capacity to the size.

    With std::vector, if you have std::vector<int> myvec, myvec.size() <= myvec.capacity(), but myvec.capacity() can be (theoretically) arbitrarily large.  They wanted to provide a way to make the vector reduce the amount of memory used by the vector.  I'm not sure offhand if there is already an easy way to do this or not.  In any case, they made this placeholder class to use instead of std::vector until they could figure out how to make it work... they never did.
     

     

    There is an easy way to reduce the capacity, it's called the "swap trick".

     

    vector<int> v;

    // ... fill up v with elements ...

    vector<int>(v.begin(), v.end()).swap(v); // reduce capacity to size

     

    This constructs a new unnamed vector with exactly the elements in v, then exchanges the contents with v, then implicitly deallocates the memory previously associated with v.



  • I think that's the solution they settled on.  Below that class declaration was a small function that took a reference to a std::vector and did what you are describing.  They just never took their derived class out because it was used all over the place.

    As a side note, I spoke with the guy in charge of that code and he agreed to remove it from the code entirely.
     


Log in to reply