I was trying to see if I can make a heterogeneous type that can only contain one of several types in its lifetime(an either pattern), and I want to do this:
//strong typed (heterogeneous) container
template<typename list>
struct STC
{
template<typename a>
STC(const a& value) :hc_(value), index_(TMP::elem_index<a, list>::value) {}
template<typename a>
STC(a&& value) : hc_(value), index_(TMP::elem_index<a, list>::value) {}
//imaginary compile time const
constexpr size_t index()const { return index_; }
typename TMP::index<list,index()>::type get() { return c_.get<index()>(); }
operator typename TMP::index<list,index()>::type ()const { return get(); }
private:
union_magic<list> c_;
const size_t index_;
};
where typename list
is a template meta type list, TMP::elem_index
is a template meta function for retriving the index of an list element, and TMP::index
is a meta function for retriving element with known index.
It seems to me that there is no way to cross the line between class data member and compile time constant. Am I missing something? Is this the wrong approach? Or it's just something impossible to do in c++, and has to be resolved in runtime?
As for how do I use the container:
void call_with(char c)
{
std::cout << "calling function with char type: " << c << std::endl;
}
void call_with(int i)
{
std::cout << "calling function with int type: " << i<< std::endl;
}
int main()
{
STC<Cons<int, Cons<char, Nil>>> value(1);
call_with(value);
}
should display "calling function with int type: 1".