【问题标题】:Templated data type that might have an array of length zero可能具有长度为零的数组的模板化数据类型
【发布时间】:2019-09-09 16:30:14
【问题描述】:

我想要一个数据类型,它有一定数量的模板化额外信息,但额外信息可能不存在。

我的第一个想法就是这样做:

template <size_t SIZE>
class Data
{
    int a;
    int bs[SIZE];

public:
    Data(int a, int bs[SIZE]) : a(a),  bs(bs) {};
};

但是在阅读了其他关于零大小数组的问题之后,如果我用SIZE = 0 实例化模板,这似乎会导致麻烦,在这种情况下,如果我尝试调用带有Data&lt;0&gt; d(1, {});的构造函数

一个明显的解决方案是为这种情况创建一个额外的类型:

class DataZero
{
    int a;

public:
    Data(int a) : a(a) {};
};

但我非常希望有一个解决方案,它可以让我将模板保存在任何地方,如果可能的话,我可以写Data&lt;0&gt;。另外,也许我只是实例化了Data&lt;0&gt; 错误,但非常感谢您对此事的任何意见。

【问题讨论】:

  • allow me to write Data&lt;0&gt; - 这会做什么?
  • 如果可以将其模板化,则不必引入新类型 DataZero
  • std::array&lt;int, SIZE&gt; bs; ?
  • Data(int a, int bs[SIZE]) : a(a), bs(bs) {} 无效,c-array 不可复制,(而int bs[SIZE] 实际上是int* bs,您可能需要Data(int a, int (&amp;bs)[SIZE]) 代替(并使用std::copy 进行初始化))。
  • 如果我使用您在下面建议的解决方案,std::array 会使用我的语法正确复制吗?

标签: c++ arrays templates types


【解决方案1】:

您可以使用模板专业化来做到这一点。

template <>
class Data<0>
{
    int a;

  public:
    Data(int a) : a(a) {}
};

但是,当创建Data&lt;0&gt; 类型的对象时,您必须使用

Data<0> d(1);

如果必须支持使用

Data<0> d(1, {});

您可以使用被忽略的占位符参数。

template <>
class Data<0>
{
    int a;

  public:
    Data(int a, int b) : a(a) {}
};

【讨论】:

  • 太棒了,这正是我需要但不知道的!谢谢!
【解决方案2】:

使用std::array 代替常规数组。

std::array 已经专门化了 0。

在 C++20 中,

  • [[no_unique_address]] 属性允许编译器在SIZE==0 的情况下进行优化。
  • requires 允许将两个构造函数放在同一个类中,并根据实例化丢弃错误:
template <size_t SIZE>
class Data
{
    int a;
    [[no_unique_address]] std::array<int, SIZE> bs;

public:
    Data(int a) requires (SIZE == 0) : a(a),  bs() {}
    Data(int a, std::array<int, SIZE> bs) requires (SIZE != 0) : a(a),  bs(bs) {}
};

【讨论】:

  • 另外,感谢您的回答。我应该注意到我想保留静态数组,但 @r-sahu 的答案非常适合这种情况。
猜你喜欢
  • 2020-04-12
  • 2014-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 2011-07-26
  • 2018-07-17
相关资源
最近更新 更多