【问题标题】:Can I pass &std::array<> as a void*?我可以将 &std::array<> 作为 void* 传递吗?
【发布时间】:2019-02-16 11:36:25
【问题描述】:

我有一些遗留的 C 代码,我用 C++ 接口封装了这些代码,供新的 C++ 代码使用。 C 代码使用 void* 从文件加载数据。它根据您发送的枚举标签知道要在内部加载多少数据:

bool load_data( TAG_TYPE tag, void* data );

我的 C++ 包装器看起来像:

template<typename T>
T load( TAG_TYPE tag ) {
    T data;
    bool success = load_data( tag, &data );
    assert( success );
    return data;
}

这增加了一些类型安全性,并且对于 C++ 代码更简洁。我们可以使用 auto & const:

const auto foo = load<int>( TAG_NUM_POINTS );

现在有人需要从文件中加载一个数组。他们想使用 std::array 因为这是 C++。

const auto foo = load<std::array<int, 3>>( TAG_RGB_VALUE );

这样安全吗?它似乎编译并运行良好。在幕后,它会将&amp;std::array&lt;int, 3&gt; 作为data 值传递,而不是首选的data.data()

这似乎是我想做模板专业化的一个领域,但是我需要为 std::array 的类型和大小添加模板参数?这有可能吗?这是要走的路吗?

【问题讨论】:

  • 这是一个应该工作,但不保证由标准。没有什么能阻止std::array 的实现者添加一个或两个额外的簿记变量,但我想看看他们认为通过这样做解决了什么样的问题。重新思考:在 C++14 之后,措辞可能已经收紧了。我并没有声称自己很了解 C++17。
  • @user4581301 我不知道他们是否可以添加一个或两个额外的簿记变量。来自cppreference:“此容器是一种聚合类型,其语义与将 C 样式数组 T[N] 作为其唯一非静态数据成员的结构相同。”并且构造函数是“隐式声明的”并且“遵循聚合初始化的规则”
  • @NirFriedman 绝对不是重复的。这个问题与功能模板专业化无关,尽管它确实将其作为可能的解决方案提出
  • 我收回了。由于std::array 的第一个成员必须是数组,所以对于提问者来说,在数组后面添加了什么对于提问者来说并不重要。

标签: c++ c++11 templates std template-specialization


【解决方案1】:

std::array&lt;&gt; 中存在一个名为data() 的方法。它允许您访问内部数据而不必担心实现。你可以在这里阅读更多关于它的信息https://en.cppreference.com/w/cpp/container/array/data

一个例子

bool load_data( TAG_TYPE tag, void* data );

template<typename T>
std::array<T> load( TAG_TYPE tag ) {
    std::array<T> data;
    bool success = load_data( tag, data.data() );
    assert( success );
    return data;
}

【讨论】:

  • 您的代码无法编译,因为std::array 需要大小。它也不适用于 OP 的 load&lt;int&gt;( TAG_NUM_POINTS ) 示例。
猜你喜欢
  • 2016-12-17
  • 2011-07-17
  • 2012-02-09
  • 1970-01-01
  • 1970-01-01
  • 2014-03-05
  • 2015-12-29
  • 2021-06-02
  • 2012-05-15
相关资源
最近更新 更多