#include <iostream>
#include <vector>
#include <string>
using namespace std;
int value = 'A';
// static assert helper
template <bool b>
struct StaticAssert {};
template <>
struct StaticAssert<true>
{
static void test(const string& s) {}
};
// helper struct that saves us from partially specialized method overloads
template < class RequestedType, class ActualType, class TContentHolder >
struct Getter;
// holds a vector of type TContent, recursively inherits from holders of other types
template < class TContent, class TAddContentHolders >
class ContentHolder : public ContentHolder< typename TAddContentHolders::ContentType, typename TAddContentHolders::AdditionalContentTypes >
{
public:
typedef TContent ContentType;
typedef TAddContentHolders AdditionalContentTypes;
private:
typedef ContentHolder< typename TAddContentHolders::ContentType, typename TAddContentHolders::AdditionalContentTypes > ParentType;
public:
vector< ContentType > mVector;
ContentHolder()
{
for ( int i = 0; i < 5; ++i )
{
mVector.push_back( ContentType(value++) );
}
}
virtual ~ContentHolder() {}
template < class RequestedType >
RequestedType get()
{
return Getter< RequestedType, ContentType, ContentHolder < TContent, TAddContentHolders > >::get(this);
}
};
// specialization for ending the recursion
template < class TContent >
class ContentHolder< TContent, bool >
{
public:
typedef TContent ContentType;
typedef bool AdditionalContentTypes;
vector< ContentType > mVector;
ContentHolder()
{
for ( int i = 0; i < 5; ++i )
{
mVector.push_back( ContentType(value++) );
}
}
virtual ~ContentHolder() {}
template < class RequestedType >
RequestedType get()
{
return Getter< RequestedType, ContentType, ContentHolder< ContentType, bool > >::get(this);
}
};
// default getter: forwards call to parent type
template < class RequestedType, class ActualType, class TContentHolder >
struct Getter
{
static RequestedType get(TContentHolder* holder)
{
cout << "getter 1" << endl;
return Getter< RequestedType, typename TContentHolder::ContentType, typename TContentHolder::AdditionalContentTypes >::get(holder);
}
};
// specialized getter for when RequestedType matches ActualType: return value from holder
template < class RequestedType, class TContentHolder >
struct Getter< RequestedType, RequestedType, TContentHolder >
{
static RequestedType get(TContentHolder* holder)
{
cout << "getter 2" << endl;
return holder->mVector[0];
}
};
// specialized getter for end of recursion
template < class RequestedType >
struct Getter< RequestedType, RequestedType, bool >
{
static RequestedType get(ContentHolder< RequestedType, bool >* holder)
{
cout << "getter 3" << endl;
return holder->mVector[0];
}
};
// This is the getter in question
template < class RequestedType, class NonMatchingType >
struct Getter< RequestedType, NonMatchingType, bool >
{
static RequestedType get(ContentHolder< NonMatchingType, bool >* holder)
{
cout << "getter 4" << endl;
//StaticAssert<false>::test("Type not in list");
return 0;
}
};
class MyHolder : public ContentHolder< int, ContentHolder< bool, ContentHolder< char, bool > > >
{
};
int main() {
MyHolder h;
cout << h.get<int>() << endl;
cout << h.get<bool>() << endl;
cout << h.get<char>() << endl;
//cout << h.get<float>() << endl;
return 0;
}