【问题标题】:How to build a type generator class based on the input data type and container type(by template arguments)?如何根据输入数据类型和容器类型(通过模板参数)构建类型生成器类?
【发布时间】:2022-08-03 17:13:42
【问题描述】:

在我的微型演示程序中存在两种基本数据类型,由以下类表示:

struct FloatDataTypeDescriptor {
  using dtype = float;
};
struct Uint8DataTypeDescriptor {
  using dtype = uint8_t;
  uint8_t zero_point_;
  float scale_;
};

从概念上讲,数据类型描述符和数据实际持有者(可能是std::arraystd::unique_ptrstd::vector...)紧密耦合在一起,所以我决定使用std::pair 来表示数据块,例如:

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[]>;
// ...

虽然这可以工作,但是到处写这样的模板别名有点乏味。所以我想到了使用部分特化来创建一个“类型生成器”,通过提供的模板参数生成所需的std::pair&lt;&gt; 类型。

// 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>>;
};

并像这样使用它:

using a = PairedTypeGenerator<Uint8TypeDescriptor, std::vector>::type;

我尝试在模板模板参数Container 中使用可变参数模板包。由于某些Container 可能需要数据类型以外的额外参数(如vector Allocator / unique_ptr Deleter)。它没有用,clang 告诉我:

<source>:21:53: error: template argument for template template parameter must be a class template or type alias template
struct EmbeddingPairedTypeGenerator<TypeDescriptor, std::vector<typename TypeDescriptor::dtype>> {

所以我想知道:

  1. 如何正确编写那些偏特化类来处理上面的sn-p?
  2. 它甚至可用吗?例如std::arrayContainer 类型需要一个非类型模板参数,不能被参数包匹配。

标签: c++ c++11 templates template-meta-programming template-specialization


【解决方案1】:

std::vector&lt;typename TypeDescriptor::dtype&gt; 不是模板。它是一种类型。在专业化中,您希望专门针对 std::vector 而不是针对它的特定实例化。该错误是由于主模板期望模板作为第二个参数而不是类型。

#include <vector>

struct FloatDataTypeDescriptor {
  using dtype = float;
};
struct Uint8TypeDescriptor {
  using dtype = unsigned;
};

// 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> {
                                    //        ^^^------------------------
  using type = std::pair<TypeDescriptor, std::vector<typename TypeDescriptor::dtype>>;
};

using a = PairedTypeGenerator<Uint8TypeDescriptor, std::vector>::type;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-20
    • 2019-11-10
    • 2019-11-16
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    相关资源
    最近更新 更多