If You want to read data from vector of std::tuple You can use :
#include <algorithm>
#include <iostream>
#include <sstream>
#include <tuple>
#include <variant>
#include <vector>
using example = std::tuple<unsigned long, double, int, float, double>;
using var = std::variant<unsigned long, double, int, float>;
enum example_index
{
a = 0,
b = 1,
c = 2,
d = 3,
e = 4,
MAX = e
};
std::stringstream &operator<<(std::stringstream &stream, const example &e)
{
std::apply([&stream](auto &&...args) { ((stream << args << ";"), ...); }, e);
return stream;
}
int main()
{
std::vector<example> example_v;
auto tuple_example = std::make_tuple(10, 5.5, -3, 2.2, 4.1);
example_v.emplace_back(tuple_example);
example_v.emplace_back(tuple_example);
std::stringstream stream = std::stringstream();
for (auto &e : example_v)
{
stream << e << std::endl;
}
std::cout << stream.str();
return 0;
}
Can I assign value to std::tuple in function which takes index and std::variant of all possible data types of tuple ?
I tried :
#include <algorithm>
#include <iostream>
#include <sstream>
#include <tuple>
#include <variant>
#include <vector>
using example = std::tuple<unsigned long, double, int, float, double>;
using var = std::variant<unsigned long, double, int, float>;
enum example_index
{
a = 0,
b = 1,
c = 2,
d = 3,
e = 4,
MAX = e
};
bool set_value(example &e, var value, example_index index)
{
if (index > example_index::MAX)
{
return false;
}
std::get<index>(e) = value;
return true;
}
std::stringstream &operator<<(std::stringstream &stream, const example &e)
{
std::apply([&stream](auto &&...args) { ((stream << args << ";"), ...); }, e);
return stream;
}
int main()
{
example e;
set_value(e, 10, example_index::a);
set_value(e, 5.5, example_index::b);
set_value(e, -3, example_index::c);
set_value(e, 2.2, example_index::d);
set_value(e, 4.1, example_index::e);
std::stringstream stream;
stream << e << std::endl;
std::cout << stream.str() << std::endl;
return 0;
}
But I'm getting error : No matching function for call to 'get'.
I know i can assign it static
example e;
std::get<0>(e) = 1;
std::get<1>(e) = 2.0;
std::get<2>(e) = 3;
std::get<3>(e) = 4.5f;
std::get<4>(e) = 5.6;
std::stringstream stream;
stream << e;
std::cout << stream.str() << std::endl;
I also know it can be passed using switch case statement for each field but I feel like it's too much ...
You can use template metaprogramming for your set_value function:
template<example_index INDEX, typename T>
bool set_value(example &e, T value)
{
static_assert(INDEX<=example_index::MAX,"bad index");
std::get<INDEX>(e) = value;
return true;
}
The call site looks like this:
set_value<example_index::a>(e, 10 );
That way to compile will generate all versions of set_value that are used in the program.