установите значение в std::tuple, используя функцию, которая принимает индекс std::get
Если вы хотите прочитать данные из вектора std::tuple, вы можете использовать:
#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;
}
Могу ли я присвоить значение std::tuple в функции, которая принимает индекс и std::variant всех возможных типов данных кортежа?
Я пытался :
#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;
}
Но я получаю сообщение об ошибке: нет соответствующей функции для вызова get.
Я знаю, что могу назначить его статическим
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;
Я также знаю, что его можно передать с помощью оператора Switch Case для каждого поля, но мне кажется, что это слишком много...
1 ответ
Вы можете использовать метапрограммирование шаблонов для своей функции set_value:
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;
}
Сайт вызова выглядит так:
set_value<example_index::a>(e, 10 );
При такой компиляции будут созданы все версии set_value, используемые в программе.