将std::array的一些元素强制转换为较短的std::array
Cast some elements of std::array to shorter std::array
是否可以强制转换std::array<double, 4>
到std::array<double, 3>
?
例如:
void f(std::array<double,3> &);
...
int main() {
std::array<double,4> a;
...
f(/* pass a[1], a[2] and a[3] */);
}
编辑:
上下文:有几个晶格自旋(点)特性是由不同的函数(不同的f()-s)计算的。这些函数应该填充数组的不同部分。(数组不能是结构化的,因为数字元素取决于编译时参数。)这些f()-s被调用了数百万次。
在保持功能不变的同时,没有比更简单的方法了
std::array<double, 3> temp{a[1], a[2], a[3]};
f(temp);
相反,让您的函数使用两个迭代器,使其工作的范围远不止一个包含3个元素的std::array
:
template<typename Iter>
void f(Iter first, Iter last);
f(std::next(std::begin(a)), std::end(a));
这里有一个不使用迭代器的编译时解决方案,因为你似乎认为它们会增加开销:
template<size_t N> void f(double*);
...
int main() {
std::array<double,4> a;
...
f<3>(a.data());
}
IMHO,这并不比只传递两个迭代器更好。如果f
可以内联,编译器将能够优化从a.begin()
到a.begin()+3
的遍历,以及如果您将其传递给array<double, 3>
(如果您注意的话,您会注意到常数3
在所有情况下都是常数。)
您可以尝试这个替代方案。因此,您的函数将接受您想要的任何数组。应在.h
文件中定义
template<typename Type> void f(Type &arr)
{
for (auto it=arr.rbegin(),int i=0;it!=arr.rend();++it,i++)
{
if (i < N)//<-- Your last N elements of arr
std::cout << (*it) << std::endl;
}
}
呼叫方式如下:
int main()
{
std::array<double,3> test1;
f(test1);
}
注意:您没有指定如何获得最后一个N
元素。但是有几种方法。
由于std::array
是标准布局类型(当然,只要内部类型是),而且布局与普通的旧数组兼容,下面的强制转换应该可以满足您的需要。
f(reinterpret_cast<std::array<double,3>&>(a));
现在,这个演员阵容非常丑陋,所以需要一些语法糖:
template<size_t N2, typename T, size_t N1>
std::array<T, N2> resize_array(std::array<T,N1> &a, int offset)
{
return reinterpret_cast<std::array<T,N2>&>(a[offset]);
}
...
f(resize_array<3>(a, 1));
如果偏移量是编译器常量,您可以将其作为模板参数,甚至可以让编译器检查范围!但这是留给读者的练习。
您可以尝试联合:
int main() {
union U {
std::array<double,4> a;
struct {
double dummy;
std::array<double,3> a;
} s;
} u;
std::array<double,4> &a = u.a;
std::array<double,3> &a1 = u.s.a;
...
f(a1);
}
它应该可以工作,但我不完全确定它的便携性。。。
相关文章:
- C++11 中不同类型的对象的 std::array 的替代方案
- constexpr begin of a std::array
- C++如果必须在编译时确定大小,std::array 有什么意义?
- 标准::unordered_map 中的 std::array 的值初始化
- 确保编译时的特定 std::array 位置
- std::array的长度有大小限制吗?
- 将 std::array 移动到另一个 std::array
- 为什么 std::shared_ptr 被认为是"heavy"和"expensive",但 std::array "same perfprmance as plain (c-style) arrays
- std::bind on statd::array 的运算符 []
- 检查输入 std::array 指针数据是否等于某个常量数组
- 如何读/写或遍历 std::array 中的特定元素范围?
- 是否可以使用 std::array 作为 POD 结构的数据容器?
- 如何在C++中传递一个大小未知的 std::array?
- 在现代C++中将 std::array<std:::array<T,N>> 转换为 std::vector<T>
- 在 C++ 中访问 std::array<std::array> 元素
- 将标量+std::array+std::tuple转换为一个大元组
- 如何初始化 std::array<std::array<T, 2>, 2> 的对象?
- 初始化 std::p air<double, std::array<std::p air<double, double>, 3> >
- 单独移动数组(raw array, std::array, std::vector)的每个元素
- 包装方法返回 c++ std::array<std::string, 4> in cython