How to create combinations of several vectors OF DIFFERING TYPES without hardcoding loops in C++

90 Views Asked by At

The following question asks about finding "all combinations" of n vectors of THE SAME TYPE, e.g. std::string: Howto create combinations of several vectors without hardcoding loops in C++?

(This means, concatenating all possible combinations to strings and printing these.)

So, for

std::vector<std::string> v1{ "T", "C", "A" };
std::vector<std::string> v2{ "C", "G", "A" };
std::vector<std::string> v3{ "C", "G", "T" };

we'd get:

TCC
TCG
TCT
TGC
TGG
TGT
TAC
TAG
TAT
CCC
CCG
CCT
CGC
CGG
CGT
CAC
CAG
CAT
ACC
ACG
ACT
AGC
AGG
AGT
AAC
AAG
AAT

One answer using recursion is this: https://stackoverflow.com/a/1700227/7302562

Is the same possible with vectors holding different types, by using variadic templates?

So, for example:

std::vector<std::string> v1{ "T", "C", "A" };
std::vector<int> v2{ 1, 2, 3 };
std::vector<float> v3{ 1.1, 2.2, 3.3 };

should gain a string like this (the exact formatting is not so important; I'm just interested in the structure of the function):

T-1-1.1
T-1-2.2
...
T-2-1.1
T-2-2.2
...
A-3-3.3

(And if so, can we pass a std::function or something similar along with the vectors to specify what to do, instead of doing the hard-coded concatenation?)

(I'm just beginning to wrap my head around variadic templates, so my first attempt is not really showable... And I hope the question is not in itself stupid...)

1

There are 1 best solutions below

3
Lecus On BEST ANSWER

You can use std::variant. It's a template that lets you have two or more types in a variable. Example:

std::variant<std::string, int> myVariant = 3;

The only problem that has this implementation is that you will need to know the type of the variable if you want to get its value. Example:

if(holds_alternative<int>(myVariant){
   std::get<int> myVariant // 3
}

But, if you want to use just primitive types or strings, it will be easier:

std::vector<std::variant<std::string, int>> v1{ "T", 4, "A", 83 };

If you want to use arbitrary types, you can also use std::any. It allows every type.

std::vector<std::any> v1{"T", 4, 2.5, '\n'} // ... and the types you want