установите значение в 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, используемые в программе.

Другие вопросы по тегам