Reputation: 1721
Please help me understand how to create a derived class from vector
. I understand deriving from standard containers is discouraged.
Here is my example:
// Example program
#include <vector>
using namespace std;
struct Card
{
int suit;
int value;
Card(int pSuit, int pValue) : suit(pSuit), value(pValue)
{
}
};
struct CardVector : public vector<Card>
{
void removeCards(const CardVector &cardArr)
{
// todo
}
};
int main()
{
CardVector cardArr1;
cardArr1.push_back(Card(1,1)); // works
vector<Card> cardArr2{Card(1,1)}; // works
CardVector cardArr3{Card(1,1)}; // doesn't compile
return 0;
}
which gives the compile error
In function 'int main()':
30:32: error: no matching function for call to 'CardVector::CardVector(<brace-enclosed initializer list>)'
30:32: note: candidates are:
16:8: note: CardVector::CardVector()
16:8: note: candidate expects 0 arguments, 1 provided
16:8: note: CardVector::CardVector(const CardVector&)
16:8: note: no known conversion for argument 1 from 'Card' to 'const CardVector&'
16:8: note: CardVector::CardVector(CardVector&&)
16:8: note: no known conversion for argument 1 from 'Card' to 'CardVector&&'
Upvotes: 1
Views: 331
Reputation: 117298
You can do it by using
the base class constructor (and other methods too):
#include <iostream>
#include <vector>
#include <string>
struct Card {
std::string name;
};
class CardVector : public std::vector<Card> {
using std::vector<Card>::vector; // <- like so
void removeCards(const CardVector& cardVector) {}
void appendCards(const CardVector& cardVector) {}
};
int main() {
Card a{"A"}, b{"B"};
CardVector cv = {a, b};
for(auto& c : cv) {
std::cout << c.name << "\n";
}
}
... but since the destructor of std::vector
isn't virtual, be sure that you'll never delete objects though a base class pointer.
To avoid future headache, use composition and create proxy functions for those you need to support.
Lightness Races in Orbit shed some light on the compilation errors:
The cause was a missing ctor taking a std::initializer_list
and to fix that you can either add one constructor (taking a std::initializer_list<Card>
as an argument) or re-use the base class ctor as I did above. LRiO also shared VS to this day does an extra copy of ctor args when you inherit ctors like this which is certainly worth taking in consideration if you're using VS.
Upvotes: 4