是否可以投射最后3个元素
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被称为数百万次。
答案 0 :(得分:7)
在保持功能不变的情况下,没有更简单的方法可以做到这一点:
std::array<double, 3> temp{a[1], a[2], a[3]};
f(temp);
相反,让你的函数接受两个迭代器,并使它比std::array
有3个元素的工作更多:
template<typename Iter>
void f(Iter first, Iter last);
f(std::next(std::begin(a)), std::end(a));
答案 1 :(得分:1)
这是一个不使用迭代器的编译时解决方案,因为你似乎认为它们会增加开销:
template<size_t N> void f(double*);
...
int main() {
std::array<double,4> a;
...
f<3>(a.data());
}
恕我直言,这并不比传递两个迭代器更好。如果可以内联f
,编译器将能够优化从a.begin()
到a.begin()+3
的遍历以及如果您通过它array<double, 3>
(如果您正在关注您)我注意到常量3
在所有情况下都是常数。)
答案 2 :(得分:0)
您可以尝试这种替代方案。因此,您的函数将接受您想要的任何数组。它应该在.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
个元素。但有几种方法。
答案 3 :(得分:0)
由于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));
如果偏移量是编译器常量,你可以使它也成为模板参数,你甚至可以让编译器检查范围!但这仍然是读者的一种练习。
答案 4 :(得分:-2)
你可以尝试一个联盟:
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);
}
它应该可行,但我不完全确定可移植性......