Something based on the CRTP idiom and a bit of sfinae could probably solve it:
template <class D, class T>
class BeliefSet : public Belief<T>
{
private:
std::vector<T> m_Facts;
template <class Iter>
void SetFactsInternal(char, Iter IterBegin, Iter IterEnd, bool Append = false)
{
if(!Append)
{
m_Facts.clear();
}
m_Facts.insert(m_Facts.end(), IterBegin, IterEnd);
}
template <class Iter, typename U = D>
auto SetFactsInternal(int, Iter IterBegin, Iter IterEnd, bool Append = false)
-> decltype(static_cast<U*>(this)->OverloadedSetFacts(IterBegin, IterEnd, Append), void())
{
static_cast<U*>(this)->OverloadedSetFacts(IterBegin, IterEnd, Append);
}
public:
template <typename... Args>
void SetFacts(Args&&... args)
{
SetFactsInternal(0, std::forward<Args>(args)...);
}
};
Your derived class can implement OverloadedSetFacts
member function to overload SetFacts
.
Moreover, your derived class must inherit from BeliefSet
as it follows:
struct Derived: BeliefSet<Derived, MyTType>
{
//...
};
That is the key concept behind the CRTP idiom after all.
It follows a minimal, working example (in C++14 for simplicity):
#include<iostream>
template <class D>
class Base {
private:
template <class C>
auto internal(char, C) {
std::cout << "internal" << std::endl;
}
template <class C, typename U = D>
auto internal(int, C c)
-> decltype(static_cast<U*>(this)->overloaded(c), void()) {
static_cast<U*>(this)->overloaded(c);
}
public:
template <typename... Args>
auto base(Args&&... args) {
internal(0, std::forward<Args>(args)...);
}
};
struct Overloaded: Base<Overloaded> {
template<typename T>
auto overloaded(T) {
std::cout << "overloaded" << std::endl;
}
};
struct Derived: Base<Derived> {};
int main() {
Overloaded over;
over.base(0);
Derived der;
der.base(0);
}
As you can see, you can provide a default implementation in your base class and override it in the derived class if needed.
See it on wandbox.
virtual
function that should allow to add mutliple values of an STL container to the internal vectorm_Facts
. – Euroclydon