You seem to want std::tuple
or hana::tuple
. It's entirely possible to change you class so that you don't need to send the type each time.
However, you will still need to pass something as a template parameter. Usually, the index of the variable or the index of the type is enough.
The tuple
class from the standard library does it like this:
std::tuple<int, std::string> tup;
std::get<0>(tup) = 5; // assign the int
std::get<1>(tup) = "test"; // assign the string
Boost hana skies it in a similar way, but uses operator[]
:
hana::tuple<int, std::string> tup;
tup[0_c] = 5; // assign the int
tup[1_c] = "test"; // assign the string
The _c
is a user provided literal that transform the int into an integral constant, so the value can be used at compile time.
So how you'd do it?
Simply change your int parameter to a template parameter:
int main() {
memory<float, char*> mem;
float f = mem.get<0>();
char* str = mem.get<1>();
mem.set<0>(25); // int passed, upgraded to float
return 0;
}
And then, to infer what the type is according to the index, use something like this:
template<std::size_t, typename>
struct memory_element; // no basic case
// In this case, we pass a number and a memory class
// We extend the case were the index is decremented, and we remove the first type.
template<std::size_t index, typename Head, typename... Tail>
struct memory_element<index, memory<Head, Tail...> : memory_element<index - 1, memory<Tail...>> {};
// Case where we get to 0
template<typename T, typename... Rest>
struct memory_element<0, memory<T, Rest...>> {
using type = T;
};
// Alias for ease of use
template<std::size_t I, typename M>
using memory_element_t = typename memory_element<I, M>::type;
You can the use it like this:
int main () {
// T1 is int
using T1 = memory_element_t<0, memory<int, float>>;
// T2 is float
using T2 = memory_element_t<1, memory<int, float>>;
}