-2

to の最後の 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 は何百万回も呼び出されます。

4

5 に答える 5

7

これよりも関数を同じに保ちながらそれを行う簡単な方法はありません。

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

std::array代わりに、関数が 2 つの反復子を取り、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());
}

私見ですが、これは2つのイテレータを渡すよりも優れているわけではありません。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 に答える
-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 に答える