If you really want to work with statically typed, say, std::tuple<int, int, char, int>
based on information from cin
then your compiler has to "prepare" all the possible paths at compile time. Depending on the number of types N
and the maximum length s
there are Nˢ
different possibilites, i.e., the number of possibilites grows exponentially with the maximum length s
. For very small N
and s
this could work. Since you probably prefer another approach (without statically typed, say, std::tuple<int, int, char, int>
) I prepared a C++17 example treating the types only.
#include <cstdint>
#include <iostream>
#include <tuple>
template<
class F,
class Tuple=std::tuple<>
>
auto tuplify_cin_and_call(
F f,
Tuple tuple=Tuple{}
) {
constexpr std::size_t max_tuple_size = 6;
std::cout << __PRETTY_FUNCTION__ << std::endl;
if constexpr(1 + std::tuple_size<Tuple>::value < max_tuple_size) {
std::cout << "`int`|`char` to append or `done` to finish: " << std::flush;
std::string input{};
std::cin >> input;
if(input == std::string{"int"}) {
tuplify_cin_and_call(f, std::tuple_cat(tuple, std::tuple<int>{}));
}
else if(input == std::string{"char"}) {
tuplify_cin_and_call(f, std::tuple_cat(tuple, std::tuple<char>{}));
}
else if(input == std::string{"done"}) {
return f(std::move(tuple));
}
else {
std::cout << "ERROR: invalid input" << std::endl;// `cout` or `cerr` here?
return tuplify_cin_and_call(f, std::move(tuple));
}
}
else {
std::cout << "max size reached. `done` to finish: " << std::flush;
std::string input{};
std::cin >> input;
if(input == std::string{"done"}) {
return f(std::move(tuple));
}
else {
std::cout << "ERROR: invalid input" << std::endl;// `cout` or `cerr` here?
return tuplify_cin_and_call(f, std::move(tuple));
}
}
}
int main() {
tuplify_cin_and_call(
[] (auto tuple) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
);
return 0;
}
Output (with my keyboard input included):
./main
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<>]
`int`|`char` to append or `done` to finish: int
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int>]
`int`|`char` to append or `done` to finish: char
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char>]
`int`|`char` to append or `done` to finish: asdf
ERROR: invalid input
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char>]
`int`|`char` to append or `done` to finish: char char int
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char, char>]
`int`|`char` to append or `done` to finish: auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char, char, char>]
`int`|`char` to append or `done` to finish: auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char, char, char, int>]
max size reached. `done` to finish: asdf
ERROR: invalid input
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char, char, char, int>]
max size reached. `done` to finish: done
main()::<lambda(auto:1)> [with auto:1 = std::tuple<int, char, char, char, int>]