【问题标题】:different size of array in a struct c++ using a Template使用模板的struct c ++中不同大小的数组
【发布时间】:2021-03-16 08:40:46
【问题描述】:

我有一个 typedef 结构,其中包含一个大小不同的数组,取决于运行应用程序时的大小。 应用程序应读取大小,然后创建一个具有其特定数组大小的结构。 这是我要使用的结构。

template <int N>
typedef struct Frame{
    float time;
    float zone_values[N];
}Frame;

我的问题是如何在主函数中调用它?

【问题讨论】:

  • 这可以编译吗? typedef 实际上不是必需的。只需将struct Frame {...}; 与模板一起使用即可。
  • 您必须使用动态分配。除非您想使用不同的类型,否则模板不是正确的工具。
  • 使用std::vector 会更好方式。这是运行时变量还是编译时常量?如果是前者,则无法在常规 C++ 中执行此操作。你需要一个容器。如果是后者,那么您可以这样做,但可能不想这样做。
  • 请注意,您不需要typedef - 只需将其删除(以及struct 之后的Frame)。
  • 模板是一种编译时机制,因此必须在编译时指定模板中的值N。如果您希望读取N(例如从文件中),那么您需要允许在运行时指定大小的东西。一种选择是std::vector&lt;float&gt;,它可以根据需要动态调整大小(例如,基于运行时读取的值)。

标签: c++


【解决方案1】:

您在这里混淆了编译时和运行时。您的模板参数N 必须在编译时知道才能进行编译。如果您想根据运行时条件构建可变大小的集合,我建议您改用std::vector

struct Frame
{
    float time;
    std::vector<float> zone_values;

    Frame(const std::size_t size)
     : zone_values(size)
    {    }
}

int main()
{
    const std::size_t n = calc_some_size(...);
    Frame frame(n);
}

在程序启动前就知道数组的大小时,使用模板作为工具。

当您只能在程序已经运行时确定数组的大小时,使用动态分配的容器(如 std::vector)。

【讨论】:

  • 最好让构造函数在构造函数的初始化列表中初始化zone_values(例如Frame(int size) : zone_values(size) {})。此外,std::vector 不使用 int 来指定大小 - 它使用(实现定义的)unsigned 类型,通常是 std::size_t
  • @Peter 你是对的,谢谢。我修改了代码,但有时这一点更容易理解,并且代码通过简化(如使用 int 或省略 const)更具可读性
  • 我没有建议使用const - 而且,当按值传递时,它是不必要的。
  • 我在这里总是得到相同的尺寸,我不想要那个 Frame frame1(5);框架框架2(1); std::cout
  • sizeof 运算符为您提供对象占用的字节数。那不是你想要的。要获取元素的数量,请使用std::vector::size(),就像size_t n_elements = frame1.size();
【解决方案2】:

你的结构有一个非类型模板(见https://en.cppreference.com/w/cpp/language/template_parameters) 在运行时无法确定,您应该改用 Sparkofska 提供的答案。如果您仍想使用编译时版本,您可以使用 C++17 这样做

#include <array>
#include <cstddef>

template<std::size_t N>
struct Frame {
    float time;
    std::array<float, N> zoneValues;
};

int main() {
    auto frame = Frame<3>{0.0f, std::array{1.0F, 2.0F, 3.0F}};
}

使用 C++20 你也可以这样做

auto frame = Frame{0.0f, std::array{1.0F, 2.0F, 3.0F}};

或者像这样在c++17中添加一个推导指南

#include <array>
#include <cstddef>

template<std::size_t N>
struct Frame {
    float time;
    std::array<float, N> zoneValues;
};

template<std::size_t N>
Frame(float, std::array<float, N>)->Frame<N>;

int main() {
    auto frame = Frame{0.0f, std::array{1.0F, 2.0F, 3.0F}};
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多