csteifel
csteifel

Reputation: 2934

c++ force method to be defined even though it is not inherited

So I have run into a problem in which I need a method to be defined for any types that inherit from a base class that I have created, yet I need that method to be static, is there anyway I can force it to be created?

The reason I need this I will have people be extending my base class, but I need to be able to guarantee a call to a function like so derivedType derivedType::createFromSerialized(std::string) will work to create a new instance from a serialization.

Edit: I am trying to follow Richard J. Ross III's advice and use static_assert however I am running into some problems with that and I have a feeling its due to it being called from a templated class but I can't figure out how to fix it.

template <typename indType> class population {
        static_assert(std::is_function<indType::createFromSerialized>::value, "message");
....
};

However that is giving me an error of to refer to a type member of a template parameter, use ‘typename indType:: createFromSerialized’ and no type named 'createFromSerialized' in 'class test'

The reason I am trying to use static_assert is to get a nicer error message that will give information about the proper function signature for createFromSerialized instead of just one that says its not defined.

Upvotes: 0

Views: 125

Answers (2)

n. m. could be an AI
n. m. could be an AI

Reputation: 120079

This can be done by combining static_assert and SFINAE detection technique.

template<typename T, typename V = bool>
struct has_deserialize : std::false_type { };

template<typename T>
struct has_deserialize<T,
    typename std::enable_if<
        std::is_same<decltype(&T::createFromSerialized), 
                     T* (*)(const std::string&)>::value,
        bool
        >::type
    > : std::true_type { };

template <typename T>
class test
{
  static_assert(has_deserialize<T>::value, "No suitable createFromSerialized");
};

Upvotes: 1

R Sahu
R Sahu

Reputation: 206717

What you are trying to accomplish is possible through a factory pattern very easily. Not sure whether you can accomplish it using templates.

Here's a skeleton of how I would go about implementing the serialization functionality.

SerializationFunctor.h

class Base;

class SerializationFunctor
{
   virtual Base* operator(FILE* in) const = 0;
};

Base.h

class Base
{

   bool registerSerializationFunction(std::string const& identifier,
                                      SerializationFunctor* functor);
};

ConcreteA.h

class ConcreteA
{
};

ASerializationFunctor.cc

class ASerializationFunctor : public SerializationFunctor
{
   virtual Base* operator(FILE* in)
   {
      // Restore ConcreteA and return a pointer.
   }
};

bool dummy = registerSerializationFunction("ConcreteA", new ASerializationFunctor());

ConcreteB.h

class ConcreteB
{
};

BSerializationFunctor.cc

class BSerializationFunctor : public SerializationFunctor
{
   virtual Base* operator(FILE* in)
   {
      // Restore ConcreteB and return a pointer.
   }
};

bool dummy = registerSerializationFunction("ConcreteB", new BSerializationFunctor());

Upvotes: 0

Related Questions