#include <iostream>
#include <type_traits>
#include <vector>
struct MTop {};
template <class Child>
class MainObject : public MTop
{
public:
Child * Add(char const* param);
void SetParam(char const * param) {/*some code*/}
private:
std::vector<Child*> Items;
};
template<typename T>
typename std::enable_if<!std::is_base_of<MTop, T>::value>::type
set_param_if_needed(T *, char const*) {
std::clog << "empty" << std::endl;
}
template<typename T>
typename std::enable_if<std::is_base_of<MTop, T>::value>::type
set_param_if_needed(T * const object, char const* const param) {
std::clog << "not empty" << std::endl;
object->SetParam(param);
}
template <class Child>
Child * MainObject<Child>::Add(char const* param){
Child* Temp=new Child;
set_param_if_needed(Temp, param);
Items.push_back(Temp);
return Temp;
}
class SomeData:public MainObject<int>
{
};
class SomeOtherData:public MainObject<SomeData>
{
};
int main() {
MainObject<int> intObject;
intObject.Add("param");
MainObject<SomeData> mainObject;
mainObject.Add("param");
MainObject<SomeOtherData> otherObject;
otherObject.Add("param");
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx2ZWN0b3I+CgoKc3RydWN0IE1Ub3Age307Cgp0ZW1wbGF0ZSA8Y2xhc3MgQ2hpbGQ+CmNsYXNzIE1haW5PYmplY3QgOiBwdWJsaWMgTVRvcAp7CnB1YmxpYzoKICAgQ2hpbGQgKiBBZGQoY2hhciBjb25zdCogcGFyYW0pOwogICB2b2lkIFNldFBhcmFtKGNoYXIgY29uc3QgKiBwYXJhbSkgey8qc29tZSBjb2RlKi99Cgpwcml2YXRlOgogICBzdGQ6OnZlY3RvcjxDaGlsZCo+IEl0ZW1zOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8IXN0ZDo6aXNfYmFzZV9vZjxNVG9wLCBUPjo6dmFsdWU+Ojp0eXBlCnNldF9wYXJhbV9pZl9uZWVkZWQoVCAqLCBjaGFyIGNvbnN0KikgewogICBzdGQ6OmNsb2cgPDwgImVtcHR5IiA8PCBzdGQ6OmVuZGw7Cn0KIAp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxzdGQ6OmlzX2Jhc2Vfb2Y8TVRvcCwgVD46OnZhbHVlPjo6dHlwZQpzZXRfcGFyYW1faWZfbmVlZGVkKFQgKiBjb25zdCBvYmplY3QsIGNoYXIgY29uc3QqIGNvbnN0IHBhcmFtKSB7CiAgIHN0ZDo6Y2xvZyA8PCAibm90IGVtcHR5IiA8PCBzdGQ6OmVuZGw7CiAgIG9iamVjdC0+U2V0UGFyYW0ocGFyYW0pOwp9CiAKdGVtcGxhdGUgPGNsYXNzIENoaWxkPgpDaGlsZCAqIE1haW5PYmplY3Q8Q2hpbGQ+OjpBZGQoY2hhciBjb25zdCogcGFyYW0pewogICBDaGlsZCogVGVtcD1uZXcgQ2hpbGQ7CiAgIHNldF9wYXJhbV9pZl9uZWVkZWQoVGVtcCwgcGFyYW0pOwogICBJdGVtcy5wdXNoX2JhY2soVGVtcCk7CiAgIHJldHVybiBUZW1wOwp9CiAKY2xhc3MgU29tZURhdGE6cHVibGljIE1haW5PYmplY3Q8aW50Pgp7Cn07CmNsYXNzIFNvbWVPdGhlckRhdGE6cHVibGljIE1haW5PYmplY3Q8U29tZURhdGE+CnsKfTsKCgppbnQgbWFpbigpIHsKICAgTWFpbk9iamVjdDxpbnQ+IGludE9iamVjdDsKICAgaW50T2JqZWN0LkFkZCgicGFyYW0iKTsKCiAgIE1haW5PYmplY3Q8U29tZURhdGE+IG1haW5PYmplY3Q7CiAgIG1haW5PYmplY3QuQWRkKCJwYXJhbSIpOwoKICAgTWFpbk9iamVjdDxTb21lT3RoZXJEYXRhPiBvdGhlck9iamVjdDsKICAgb3RoZXJPYmplY3QuQWRkKCJwYXJhbSIpOwp9