There exists two basic data types in my tiny demo program, represented by the below classes:
struct FloatDataTypeDescriptor {
using dtype = float;
};
struct Uint8DataTypeDescriptor {
using dtype = uint8_t;
uint8_t zero_point_;
float scale_;
};
Conceptually, the data type descriptor and data actual holder(might be std::array
, std::unique_ptr
, std::vector
...) are tightly couple together, So i decided to use std::pair
to represent the data chunk, like:
using ChunkTypeA = std::pair<FloatDataTypeDescriptor, std::vector<FloatDataTypeDescriptor::dtype>>;
using ChunkTypeB = std::pair<Uint8DataTypeDescriptor, std::vector<Uint8DataTypeDescriptor::dtype>>;
using ChunkTypeC = std::pair<FloatDataTypeDescriptor, std::unique_ptr<FloatDataTypeDescriptor::dtype[]>;
// ...
This can work though, but writing such template alias all over the place is a little bit of tedious. So i've thought of using partial specialization to create a "type generator", produce the needed std::pair<>
type by provided templates argument.
// primary template
template <typename TypeDescriptor, template<typename, typename...> class Container>
struct PairedTypeGenerator;
// partial specialization for std::vector
template <typename TypeDescriptor>
struct PairedTypeGenerator<TypeDescriptor, std::vector<typename TypeDescriptor::dtype>> {
using type = std::pair<TypeDescriptor, std::vector<typename TypeDescriptor::dtype>>;
};
And use it like:
using a = PairedTypeGenerator<Uint8TypeDescriptor, std::vector>::type;
I've tried to use variadic template pack in the template template parameter Container
. Since some Container
might need extra argument other than the data type(like vector
Allocator / unique_ptr
Deleter). It didn't work, clang tolds me:
<source>:21:53: error: template argument for template template parameter must be a class template or type alias template
struct PairedTypeGenerator<TypeDescriptor, std::vector<typename TypeDescriptor::dtype>> {
Thanks to @463035818_is_not_a_number liberal and great advice, i continue to add more specialization for std::vector
/ std::unique_ptr
/ std::array
template <typename TypeDescriptor>
struct PairedTypeGenerator<TypeDescriptor, std::vector> {
using type = std::pair<TypeDescriptor, std::vector<typename TypeDescriptor::dtype>>;
};
template <typename TypeDescriptor>
struct PairedTypeGenerator<TypeDescriptor, std::unique_ptr> {
using type = std::pair<TypeDescriptor, std::unique_ptr<typename TypeDescriptor::dtype[]>>;
};
template <typename TypeDescriptor, typename Deleter>
struct PairedTypeGenerator<TypeDescriptor, std::unique_ptr, Deleter> {
using type = std::pair<TypeDescriptor, std::unique_ptr<typename TypeDescriptor::dtype[], Deleter>>;
};
So now i can support case that std::unique_ptr
with custom Deleter, just use it as:
using Ptr = EmbeddingPairedTypeGenerator<Uint8EmbeddingDataTypeDescriptor, std::unique_ptr, decltype(&std::free)>::type;
However, for std::array
, things become much tricker, the std::array
Container type need a non type template parameter, which cannot be matched by the parameter pack. I just want to use it by some syntax similar as:
using Array = PairedTypeGenerator<Uint8DataTypeDescriptor, std::array, 512>;
Aucun commentaire:
Enregistrer un commentaire