0

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 ...

273K
  • 29,503
  • 10
  • 41
  • 64
  • C++ does not work this way. Template parameters must be known at compile time. This is fundamental, there are no workarounds or exceptions. `std::get(e)` -- `index` is known only at run time, so this won't work. There are advanced template metaprogramming techniques that deal with this, but I would expect that the chapter in your C++ textbook where this practice problem is from would explain how to do this. What, specifically, in your textbook's explanation is unclear? – Sam Varshavchik Aug 22 '23 at 21:05
  • `std::get` must get a compile-time constant. Your idea with using `switch` is likely the simplest one. – Yksisarvinen Aug 22 '23 at 21:07
  • What would happens if you set invalid/mismatching type/index (add `std::string` in your tuple)? – Jarod42 Aug 22 '23 at 21:39
  • A tuple that can be indexed with runtime indices has a special name, `std::array`. *But I have different types in there!* The second argument of `set_value` doesn't care, so why the first one does? Such data structures are not encountered in real life anyway. – n. m. could be an AI Aug 22 '23 at 21:42

1 Answers1

1

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.

kaba
  • 362
  • 1
  • 13