Expanding a parameter pack while decreasing a variable

I'm stuck trying to decrease a value while expanding a parameter pack.
This is the best pseudo-code I could come up with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <typeinfo>

template <typename ... Args>
void DisplayAll(Args ... args)
{
    std::cout << "Starting display." << std::endl;
    for(const auto& arg : {args...})
    {
        std::cout << arg << std::endl;
    }
    std::cout << "Display finished." << std::endl;
}

template <typename T>
std::string CreateArgument(int index)
{
    return std::to_string(index);
}

template <typename ... Args>
void RunTest(int StartIndex)
{
    DisplayAll(CreateArgument<Args>(StartIndex--)...);
}

int main(int argc, char *argv[])
{
    RunTest<std::string, std::string, std::string>(3);
    return 0;
}


The code shows 1, 2, 3 and (correctly) warns me about possibly invalid sequence point.
I want it to *reliably* show 3, 2, 1, but I don't know how.
Last edited on
Seems like a good place to determine the "index" of arguments would be inside the DisplayAll function.
DisplayAll cannot change :(
Also, CreateArgument will not return the arg's index.
It's unclear what exactly you want. Your statement
DisplayAll cannot change

Indicates there's some requirements you didn't share.

Is this acceptable? You were very close.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# include <iostream>
template <typename T>
std::string CreateArgument(int index) {
  return std::to_string(index);
}

template <typename... Args>
void RunTest(int start) {
  using left_to_right = int[];
  std::cout << "Starting display.\n";
  (void) left_to_right{0, (std::cout << (CreateArgument<Args>(start--)) << "\n", 0)...};
  std::cout << "Display finished.\n";
}

int main () {
  RunTest<std::string, std::string, std::string>(3);
}

http://rextester.com/EJXY16073

Last edited on
I'm quite sure start-- there brings me back to the starting point (invalid sequence point).
I've been able to work around this using compile-time lists and obscure stuff... altough I had to rework a lot of stuff to make it work.

This: http://stackoverflow.com/questions/15036063/obtain-argument-index-while-unpacking-argument-list-with-variadic-templates
Last edited on
m quite sure start-- there brings me back to the starting point (invalid sequence point).

not in mbozzi's example

If your compiler is modern enough, you can replace that left-to-right array init hack with a fold expression:

1
2
3
4
5
6
template <typename... Args>
void RunTest(int start) {
  std::cout << "Starting display.\n";
  ((std::cout << CreateArgument<Args>(start--) << "\n"), ...);
  std::cout << "Display finished.\n";
}

Topic archived. No new replies allowed.