将std :: array的一些元素转换为更短的std :: array

时间:2013-07-15 08:54:57

标签: c++ arrays c++11

是否可以投射最后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被称为数百万次。

5 个答案:

答案 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);
}

它应该可行,但我不完全确定可移植性......