3

コードがあるとします:

template<size_t num> void actLoop(float* result, const float* rvector,
                                          size_t* xs, size_t indexIn=0)
{
    for(xs[num]=0; xs[num]<N; ++xs[num])
    {
        size_t index = indexIn+xs[num]*strides[num];
        if(num>0)
            actLoop<num-1>(result,rvector,xs,index);
        else
            result[index] = work(rvector,index,xs);
    }
}

のネスト レベルでネストされたループを作成する必要がありますnum。コンパイルしようとすると、再帰が深すぎるというコンパイラ エラーが発生します。つまり、コンパイラが if(0>0) ステートメントを削除していないようです。

これを実現する良い方法はありnum=0ますか?

4

5 に答える 5

5

これif( num > 0 )はランタイム条件です。再帰はコンパイル時に発生しています。いいえ、 の特殊化を避ける方法はありませんnum = 0

しかし、なぜ専門化を作成することが問題なのnum = 0ですか?

于 2013-10-19T12:52:48.447 に答える
5

Andrei Alexandrescu は、 Going Native 2013での講演の 1 つでそれを提示しました。

template<size_t num> void actLoop(float* result, const float* rvector,
                                          size_t* xs, size_t indexIn=0)
{
    for(xs[num]=0; xs[num]<N; ++xs[num])
    {
        size_t index = indexIn+xs[num]*strides[num];
        if(num>0)
            actLoop<(num > 0 ? num-1 : num)>(result,rvector,xs,index);
        else
            result[index] = work(rvector,index,xs);
    }
}

actLoopこれは、 if numisの同じインスタンス化を参照する0ため、無限のインスタンス化が中断されます。

于 2013-10-19T13:12:30.893 に答える
0

最後の再帰呼び出しで完全なインライン化をブロックしない方法は次のとおりです。

template<size_t num> void actLoop(float* result, const float* rvector,
                                      size_t* xs, size_t indexIn=0, std::false_type )
{
  result[index] = work(rvector,index,xs);
}

template<size_t num> void actLoop(
    float* result,
    const float* rvector,
    size_t* xs,
    size_t indexIn=0,
    std::true_type unused=std::true_type()
  )
{
  for(xs[num]=0; xs[num]<N; ++xs[num])
  {
    size_t index = indexIn+xs[num]*strides[num];
    actLoop<num-1>(result, rvector, xs, index, typename std::conditional<(num>0), std::true_type, std::false_type>::type());
   }
}

-1 のケースでは、他のケースとは異なるオーバーロードを呼び出します。

別のアプローチは、関数呼び出しを a にバウンスすることです。ここでは、ケースtemplate classを専門としています。num = -1

于 2013-10-19T13:44:03.657 に答える