-2

是否可以将最后 3 个元素转换为 std::array<double, 4> to 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 被调用了数百万次。

4

5 回答 5

7

在保持功能不变的同时,没有比这更简单的方法了:

std::array<double, 3> temp{a[1], a[2], a[3]};
f(temp);

相反,让你的函数接受两个迭代器,并且让它的工作量远远超过std::array具有 3 个元素的 a:

template<typename Iter>
void f(Iter first, Iter last);

f(std::next(std::begin(a)), std::end(a));
于 2013-07-15T09:02:49.623 回答
1

这是一个不使用迭代器的编译时解决方案,因为您似乎认为它们会增加开销:

template<size_t N> void f(double*);
...
int main() {
    std::array<double,4> a;
    ...
    f<3>(a.data());
}

恕我直言,这并不比只传递两个迭代器好。如果f可以内联,编译器将能够优化从a.begin()to的遍历a.begin()+3以及如果你传递它array<double, 3>(如果你注意你会注意到3常量在所有情况下都是常量。)

于 2013-07-15T10:36:26.383 回答
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));

如果偏移量是编译器常量,您可以将其设为模板参数,甚至可以让编译器检查范围!但这留给读者作为练习。

于 2013-07-15T10:18:35.307 回答
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元素。但是有几种方法。

于 2013-07-15T09:26:30.840 回答
-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);
}

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

于 2013-07-15T09:06:32.137 回答