Home > database >  How to pass a name for convenient use of tuple?
How to pass a name for convenient use of tuple?

Time:05-23

I would like to improve the code so that it is convenient to interact with it.

struct prototype {
  template <class... T1>
  prototype(T1&&... args) {
    auto p = std::tie(args...);

    std::cout << std::get<0>(p) << std::endl;

    if constexpr(std::tuple_size_v<decltype(p)> >= 3) {
      std::cout << std::get<2>(p) << std::endl;
    }
  }
};

int option_1 = 10;
std::string option_2 = "test2";
auto option_3 = 0.41;
std::vector<int> option_4(10);

int main() {
  prototype p1(option_1, option_2, option_3, option_4);
  prototype p2(option_1, option_2, option_3);
  prototype p3(option_1, option_2);
  prototype p4(option_1);
}

i would like to do so

std::cout << option_1 << std::endl;

if constexpr (std::tuple_size_v<decltype(p)> >= 3) {
   std::cout << option_2 << std::endl;
}

I don't like this option std::get<0>(p)

Any ideas how to replace the call to tuple?

You can also see the option on https://godbolt.org/z/bT4Wzjco8

CodePudding user response:

Probably a templated lambda would be an improvement:

constexpr auto option = []<std::size_t N>(auto p) { return std::get<N-1>(p); };

which is then to be used as:

option<1>(p); // This is your option_1, invoking std::get<0>(p)

As G. Sliepen comments, you can declare the option lambda inside the body of the function and then p can be captured:

auto option = [&p]<std::size_t N> { return std::get<N-1>(p); };
// use as option<1>()

edit:

The aforementioned syntax should be valid, however I get errors when invoking the lambda with specified template parameters, i.e. option<1>(). The proposal seems to allow it, but compilers don't.

A simple workaround is to treat the generic lambda as a variable template and move the number to the variables declaration:

template <std::size_t N>
constexpr auto option =  [](auto p) { return std::get<N-1>(p); };

// Similarly you can capture p, to call it as option<1>()
template <std::size_t N>
constexpr auto option =  [&p] { return std::get<N-1>(p); };

Demo

  • Related