I have a simple union whose constructor stores its argument in the relevant member:
union Data
{
Data(int i) : _i(i) { }
Data(double d) : _d(d) { }
Data(char c) : _c(c) { }
int _i;
double _d;
char _c;
};
I then have a variadic constructor which takes arguments of these types and stores them in a vector of the union using template recursion:
template<typename... Ts>
DataStore(Ts... ts)
{
_data.reserve(sizeof...(ts));
store(ts...);
}
template<typename T, typename... Ts>
void store(T t, Ts... ts)
{
_data.push_back(t);
store(ts...);
}
void store()
{
// terminal condition
}
This will result in a series of vector::push_back calls matching the number of arguments.
Is this the most efficient/fastest way to populate the union vector?
Are there any tricks (can be specific to x86-64 / Linux) I can employ to make this faster?
Working example:
#include <iostream>
#include <vector>
union Data
{
Data(int i) : _i(i) { }
Data(double d) : _d(d) { }
Data(char c) : _c(c) { }
int _i;
double _d;
char _c;
};
struct DataStore
{
template<typename... Ts>
DataStore(Ts... ts)
{
_data.reserve(sizeof...(ts));
store(ts...);
}
template<typename T, typename... Ts>
void store(T t, Ts... ts)
{
_data.push_back(t);
store(ts...);
}
void store()
{
// terminal condition
}
std::vector<Data> _data;
};
int main()
{
DataStore d(1, 2.3, 'c');
std::cout << d._data.size() << '\n'
<< d._data[0]._i << '\n'
<< d._data[1]._d << '\n'
<< d._data[2]._c << '\n';
return 0;
}
You can initialize _data directly.
template<typename... Ts>
DataStore(Ts... ts) : _data{ts...}
{}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With