Passing std:array around
Passing std:array around
我正在尝试编写一个函数,该函数将在可变大小的std::数组上工作,例如:
std::array a<int,5>={1,2,3,4,5};
std::array b<int,3>={6,7,8};
myFunc(a);
myFunc(b);
void myFunc(std::array &p)
{
cout << "array contains " << p.size() << "elements";
}
但是,除非我指定了大小,否则它不起作用,但我希望函数从数组中获取大小。我真的不想要vector使用的复制和动态分配,我想使用std::array()分配的空间,不希望编译器为每个可能大小的数组创建函数的副本。
我曾想过创建一个类似数组的模板,但它会使用一个指向现有数据的指针,而不是自己分配数据,但我不想重新发明轮子。
这有可能吗?
template<typename T, size_t N>
void myFunc(std::array<T, N> const &p) {
cout << "array contains " << p.size() << "elements";
}
std::array
不是类,不能像类一样使用。它是一个模板,您必须实例化该模板才能获得一个可以像类一样使用的类。
此外,大小也是数组类型的一部分。如果你想要一个容器,其中的大小不是类型的一部分,那么你可以使用类似std::vector
的东西。或者,您可以编写一个适用于任何具有所需功能的对象的模板:
template<typename Container>
void myFunc(Container const &p) {
cout << "Container contains " << p.size() << "elements";
}
首选STL方式:将迭代器(按值)而不是容器传递给函数。并将您的函数模板化。
您的代码将更好地与标准算法集成,并且与std::array或其他标准容器同样有效。
例如:
template<class InputIterator>
void myFunc (InputIterator first, InputIterator last);
您真正想要的是类似于建议的std::array_ref(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3334.html)它接受任何大小,只包含一个指针范围(或指针和计数,具体取决于它的实现方式),而不是每个可能的容器类型、堆分配的容器或每个调用点的迭代器对的模板膨胀。
然而,人们忘记的另一个选项是std::initializer_list,它实际上是array_ref,一个轻量级的连续同质项视图。虽然是为构造函数设计的(其中名称"initializer"最有意义),但它们也可以由泛型函数使用。请注意,传递时不会复制内容,只是一个指针范围,这意味着您不需要(也不应该)通过引用传递initializer_list。
它允许您在函数调用中直接传递一系列数字:
void myFunc(std::initializer_list<int> p)
{
cout << "array contains " << p.size() << "elements";
}
myFunc({1, 2, 3, 4, 5});
myFunc({6, 7, 8});
或者通过一个中间变量:
std::initializer_list<int> a = {1, 2, 3, 4, 5};
std::initializer_list<int> b = {6, 7, 8};
auto c = {1, 2, 3, 4, 5};
auto d = {6, 7, 8};
myFunc(a);
myFunc(b);
myFunc(c);
myFunc(d);
甚至,它似乎是从固定大小的std::数组改编而来的,使用了一个构造函数重载,该重载采用了一个开始/结束对。
std::array<int, 5> e = {1, 2, 3, 4, 5};
std::array<int, 3> f = {6, 7, 8};
myFunc(std::initializer_list<int>(e.data(), e.data() + e.size()));
myFunc(std::initializer_list<int>(f.data(), f.data() + f.size()));
不过,我在cppreference.com上没有看到这个构造函数重载,在N4166中也没有。因此,这种过载可能不是标准的,只能在Dinkumware的STL(Visual Studio 2015使用)中找到。此外,数组/向量没有隐式转换,最终只能编写一个中间辅助模板函数(或者编写比简单传递两个范围更多的代码),这太糟糕了。理想情况下,std::array将支持一个运算符方法,该方法将在标准中采用initializer_list或array_ref。
这是因为大小是std::array类型的一部分。
template<
class T,
std::size_t N
> struct array;
不同大小的数组是不同的类型。你应该使用一个模板函数并写:
template< typename T, size_t N>
void myFunc( std::array<T, N> const &p) {
std::cout << "array contains " << p.size() << "elements";
}
http://en.cppreference.com/w/cpp/container/array
除了已经提出的建议之外,我还想提出我的建议。
template<size_t N>
void myFunc(std::array<int, N> const &p) {
cout << "array contains " << N << "elements";
}
顺便说一下,您的变量声明需要是:
std::array<int,5> a={1,2,3,4,5}; // <int, 5> needs to move to right after array.
std::array<int,3> b={6,7,8};
- C++11 中不同类型的对象的 std::array 的替代方案
- constexpr begin of a std::array
- C++如果必须在编译时确定大小,std::array 有什么意义?
- OpenGL VBO Indexing ( How to compute Index Array)
- 标准::unordered_map 中的 std::array 的值初始化
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 确保编译时的特定 std::array 位置
- std::array的长度有大小限制吗?
- 将 std::array 移动到另一个 std::array
- 首先按给定顺序打印所有数字,然后使用 Array 打印所有字符和其他符号
- 为什么我会收到"Run-Time Check Failure #2 - Stack around the variable 'pr' was corrupted"错误?
- 为什么 std::shared_ptr 被认为是"heavy"和"expensive",但 std::array "same perfprmance as plain (c-style) arrays
- 将 **float array 从 C++ Dll 传递给 python
- std::bind on statd::array 的运算符 []
- 检查输入 std::array 指针数据是否等于某个常量数组
- 我可以安全地复制矢量<array>吗?
- 解析问题 - 预期的非限定 ID - #include <array> 编译错误
- 如何读/写或遍历 std::array 中的特定元素范围?
- 通过 host() 从 af::array 检索数据会导致错误的数据
- Passing std:array around