Consider the following code:
#include <concepts>
struct T1 {};
struct T2 {};
struct T3 {};
struct T4 {};
void bar(T1, T2, T3, T4) {
}
template<typename T>
concept IsT = std::same_as<T, T1> || std::same_as<T, T2> ||
std::same_as<T, T3> || std::same_as<T, T4>;
void foo(IsT auto x1, IsT auto x2, IsT auto x3, IsT auto x4) {
// How to order the types of x1, x2, x3, x4 and call bar(x?, x?, x?, x?)?
}
int main() {
foo(T1{},T2{},T3{},T4{}); // ok
foo(T4{},T3{},T2{},T1{}); // ok
foo(T3{},T2{},T1{},T4{}); // ok
// ...
}
My intent is simple:
The user can call
foo
in any argument order, but finallybar
will be called with the arguments in the correct order.
The trivial solution is using brute-force to divide the 24 cases, which is obviously tedious and error-prone.
Is there a non-brute force way to solve this problem? I'm using C++20.
As types are different, you might wrap them in tuple, and get correct types afterward:
void foo(IsT auto x1, IsT auto x2, IsT auto x3, IsT auto x4) {
auto t = std::tie(x1, x2, x3, x4);
bar(std::get<T1&>(t), std::get<T2&>(t), std::get<T3&>(t), std::get<T4&>(t));
}