I have a type, let's call it T. It can be of different types, and I do not know them in advance: int, double, bitmap pointer... Now, I have a class, let's call it C. It should maintain a vector of queues of T. Each queue has its unique type of elements, but it is possible that C has a vector (or whatever other way of maintaining multiple queues) with few queues of different types:
queue, queue, ...
So my question is: is there a way to pass variable number types to a class? Example: I need to get <int, double, double, int> and in a constructor, to create corresponding queues, plus I will need a function to get/put data to a particular queue (say, queue No 3 in a list).
I know about variadic templates, but can not figure how to use it: it looks like I have to do it recursively, and I am not that advanced...
I can do it using "any", but then get/put will have "any" as well, and I do not know how to do a type check, so the user doesn't send a double instead of string, or something like that.
Any ideas? Thanks.
CodePudding user response:
It's actually not that complicated. You don't even need recursion. Just std::tuple
#include <tuple>
#include <queue>
template <class... Args>
struct C
{
std::tuple<std::queue<Args>...> queues_;
template <std::size_t I>
auto& queue_at()
{
return std::get<I>(queues_);
}
};
auto test()
{
C<int, double, bool> c;
std::queue<int>& q1 = c.queue_at<0>();
std::queue<double>& q2 = c.queue_at<1>();
}
CodePudding user response:
You can use variadic template with recursive inheritance:
#include <queue>
#include <string>
template <typename First, typename... Rest>
struct Base : Base<First>, Base<Rest...> {
};
template <typename First>
struct Base<First> {
std::queue<First> q;
};
int main (){
auto f = Base<int, std::string>{};
static_cast<Base<int>>(f).q.emplace(32);
static_cast<Base<std::string>>(f).q.emplace("sdf");
// not allowed
// static_cast<Base<float>>(f).q.emplace(1231.2);
}