Let we have a struct Record{uint8_t x, y;};
, a container Container<Record>
of structs and a struct Transposed{Container<uint8_t> x,y};
. Container c
is a template which first arg is a type of value, all of the rest args have default values. For example it can be a std::vector
(the rest args are types) or std::span
(the rest arg is a value). The template should work with all of them. Also we may like to pass tne rest of template arguments to underlying template.
How we can get the Transposed
from the container using templates?
I have tried variadic templates,
#include <iostream>
#include <vector>
template <typename value_type=uint8_t> struct Record{
value_type x, y;
};
template<typename value_type, typename value_type2=uint8_t> class ContainerA: public std::vector<value_type>{
value_type2 b=1u;
};
template<typename value_type, uint8_t int_value=1u> class ContainerB: public std::vector<value_type>{};
template<typename value_type, template <typename ...> typename container_type> class Transposed{
container_type<value_type> x, y;
public:
Transposed(container_type<Record<value_type>> & recs){
x.reserve(recs.size());
y.reserve(recs.size());
x.resize(recs.size());
y.resize(recs.size());
size_t i=0;
for(auto &rec :recs){
x[i] = rec.x;
y[i] = rec.y;
++i;
}
}
};
int main(){
std::vector<Record<uint8_t>> recsV{
{1, 2},
{3, 4}
};
Transposed trV{recsV};
std::cout<<"vec"<<std::endl;
ContainerA<Record<uint8_t>> recsA{
{1, 2},
{3, 4}
};
Transposed trA{recsA};
std::cout<<"A"<<std::endl;
/*ContainerB<Record<uint8_t>> recsB{
{1, 2},
{3, 4}
};
Transposed trB{recsB};
std::cout<<"B"<<std::endl;*/
return 0;
}
but it seems they cannot match both types and values. Usage of more than 1 variadic template argument is not allowed. Is it a flaw in C++ language or a deliberate design choice and do we need something like any_template_arg
keyword or should just specifying 2 variadic arguments of different types be allowed to allow this use case?