Reputation: 2934
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
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
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