3

Is there a simple way to add the current index of the arg As in include it in the lambda call so I don't need to use index++

template <typename... Args>
void Function(Args... args) {
    std::size_t size = sizeof...(Args);

    std::size_t index = 0;
    auto process = [] <typename Arg> (Arg && arg) {
        index++;
        if (typeid(arg) == typeid(char*) || typeid(arg) == typeid(const char*)) {
            std::size_t sValueSize = strlen(arg) + 1;
        }

    };
    (process(std::forward<Args>(args)), ...);
}
max66
  • 65,235
  • 10
  • 71
  • 111
docasok733
  • 117
  • 6

2 Answers2

4

You can use a helper function along with a std::index_sequence which will let you unpack both the args and indices and pass them to your lambda in the fold expression:

template <std::size_t... Indices, typename... Args>
void FunctionImpl(std::index_sequence<Indices...>, Args&&... args) {
    auto process = [] <typename Arg> (std::size_t index, Arg&& arg) {
        std::cout << index << ": " << arg << "\n";
    };
    (process(Indices, std::forward<Args>(args)), ...);
}

template <typename... Args>
void Function(Args&&... args) {
    FunctionImpl(std::make_index_sequence<sizeof...(args)>(), std::forward<Args>(args)...);
}

Live Demo

Miles Budnek
  • 28,216
  • 2
  • 35
  • 52
2

Is there a simple way to add the current index of the arg [?]

It seems to me that your use of index is a simple way. Just remember to capture it in the lambda, as suggested by QuentinUK.

Anyway, I propose another level of indirection and the use of std::index_sequence/std::index_sequence_for as follows

template <typename... Args>
void Function (Args... args)
 {
   []<std::size_t ... Is>(std::index_sequence<Is...>, auto && ... as)
    { 
      auto process = []<typename Arg>(std::size_t index, Arg && arg)
         { 
           if constexpr (    std::is_same_v<Arg, char *>
                          || std::is_same_v<Arg, char const *> )
            {
              std::size_t sValueSize = strlen(arg) + 1;

              // do something with sValueSize
            }
         };

      (process(Is, std::forward<decltype(as)>(as)), ...);
    }
   (std::index_sequence_for<Args...>{}, std::forward<Args>(args)...);
 }

Off Topic 1: the template-lambda are a C++20 feature.

Off Topic 2: I strongly suggest the use of if constexpr

    if constexpr (    std::is_same_v<Arg, char *>
                   || std::is_same_v<Arg, char const *> )

instead of your ordinary (run-time) if

    if (typeid(arg) == typeid(char*) || typeid(arg) == typeid(const char*))

because, with an ordinary if, the compiler must compile the body of the if

        std::size_t sValueSize = strlen(arg) + 1;

also when the test is false and the arg is of a type that is incompatible with strlen().

max66
  • 65,235
  • 10
  • 71
  • 111