So, I have got the following classes and methods:
Property: Has a single member of type int (named mTag)
TypedProperty: Inherits from the Property class and adds a member called mValue of type T to it.
PropertyList: A class which Maintains a std::set of Property and has an Add and Print method.
CheckSubset: A method which checks if a std::set is included in another set.
I don’t know how I should implement the CheckSubset method. Because I do not know how to iterate through a set<Property> and access to the template member (mValue). I also tried to use the includes method, which did not work (even if it worked, I would have no idea how it did!). The same problem exists in the PropertyList::Print method, where I do not know what cast should be used.
Any advice on the implementation of CheckSubset and Print methods would be appreciated!
Updated source code (using pointer)
#include <string>
#include <iostream>
#include <set>
#include <algorithm>
#include <tr1/memory>
using namespace std;
/////////////////// Property Class //////////////////////
class Property
{
public:
Property(){};
Property(const int tag)
: mTag(tag) {}
virtual ~Property() {}
int mTag;
bool operator<(const Property &property) const
{
return mTag < property.mTag;
}
};
/////////////////// TypedProperty Class /////////////////
template< typename T >
class TypedProperty : public Property
{
public:
TypedProperty (const int tag, const T& value)
: Property(tag), mValue(value){}
T mValue;
};
/////////////////////////////////////////////////////////
typedef std::tr1::shared_ptr<Property> PropertyPtr;
/////////////////// PropertyList Class /////////////////
class PropertyList
{
public:
PropertyList(){};
virtual ~PropertyList(){};
template <class T>
void Add(int tag, T value)
{
PropertyPtr ptr(new TypedProperty<T>(tag, value));
mProperties.insert(ptr);
}
void Print()
{
for(set<PropertyPtr>::iterator itr = mProperties.begin(); itr != mProperties.end(); itr++)
{
cout << ((PropertyPtr)*itr)->mTag << endl;
// What should I do to print mValue? I do not know its type
// what should *itr be cast to?
}
}
set<PropertyPtr> mProperties;
};
//////////////////// Check Subset ///////////////////////
/*
* Checks if subset is included in superset
*/
bool CheckSubset(set<PropertyPtr> &superset, set<PropertyPtr> &subset)
{
// How can I iterate over superset and subset values while I do not know
// the type of mValue inside each Property?
// I also tried the following method which does not seem to work correctly
return includes(superset.begin(), superset.end(),
subset.begin(), subset.end());
}
int main()
{
PropertyList properties1;
properties1.Add(1, "hello");
properties1.Add(2, 12);
properties1.Add(3, 34);
properties1.Add(4, "bye");
properties1.Print();
PropertyList properties2;
properties2.Add(1, "hello");
properties2.Add(3, 34);
if(CheckSubset(properties1.mProperties, properties2.mProperties)) // should be true
cout << "properties2 is subset!" << endl;
PropertyList properties3;
properties3.Add(1, "hello");
properties3.Add(4, 1234);
if(CheckSubset(properties1.mProperties, properties3.mProperties)) // should be false
cout << "properties3 is subset!" << endl;
}
For solving the problem in
Printmethod ofPropertyList, you could write aPrintmethod forTypedPropertyclass, which prints its tag and value.But about the problem in accessing
mValuewhich you want to do some operations on, I can’t think of a way using normal types and templates to get themValuewithout engaging your parent classPropertywith template type ofTypedProperty(which seems undesirable). But you could get the address ofmValueand cast it tovoid*to eliminate the type problem. This way you will face another problem, that you can not point to value of avoid*pointer, so you can not work with your pointer in parent level. Therefore, you should write a method (implemented byTypedProperty) that takes avoid*pointer and casts it to the type defined in child and perform the desired operation.For example in the following code, I assumed you want to check equality of a value in a
TypedPropertywith another one of the same type (IsEqualmethod).Now you can implement simply
CheckSubsetusingIsEqual(checking two elements would be like:superItr->IsEqual(subItr->GetValue())).