2

何年も不在だったので、C++ (技術的には Objective-C++) に戻ってきますので、ご容赦ください。テンプレートを使用して、そうでなければ大量のカット アンド ペースト コードを必要とするソリューションを実装しようとしています。以下の抜粋は、この取り組みの基本的な要点を示しています。

namespace {

    using vMAT::DOUBLE;
    using vMAT::SINGLE;
    using vMAT::INT8;
    using vMAT::UINT8;
    using vMAT::INT16;
    using vMAT::UINT16;
    using vMAT::INT32;
    using vMAT::UINT32;
    using vMAT::INT64;
    using vMAT::UINT64;

    typedef void (* swapFn)(void * vector, vDSP_Length vectorLength);

    // Functor used for template arguments.
    template <typename TypeA>
    struct swapbytes {
        swapFn fn;

        swapbytes()
        {
            if      (sizeof(TypeA) == 8) fn = vMAT_byteswap64;
            else if (sizeof(TypeA) == 4) fn = vMAT_byteswap32;
            else if (sizeof(TypeA) == 2) fn = vMAT_byteswap16;
            else if (sizeof(TypeA) == 1) fn = NULL;
            else NSCAssert(NO, @"Oops!");
        }

        void operator()(void * vector, vDSP_Length vectorLength) const
        // ..................................................... ^^^^^ Why?
        {
            if (fn != NULL) fn(vector, vectorLength);
        }
    };

    template <typename TypeA, typename ClassB>
    void
    loadFromOperation(vMAT_MATv5NumericArray * self,
                      vMAT_MATv5ReadOperation * operation,
                      TypeA a,
                      ClassB b)
    {
        swapbytes<TypeA> SwapA;
        long lenC = self.size[0] * sizeof(TypeA);
        TypeA * C = (TypeA *)malloc(lenC);
        long lenD = vMAT_Size_prod(self.size) * sizeof(ClassB);
        self.arrayData = [NSMutableData dataWithCapacity:lenD];
        self.arrayData.length = lenD;
        ClassB * D = (ClassB *)[self.arrayData mutableBytes];
        __block long idxD = 0;
        vMAT_Size123Iterator(self.size, ^(int32_t n, int32_t o, int32_t p) {
            [operation readComplete:C
                             length:lenC];
            if (operation.swapBytes) { SwapA((void *)C, lenC / sizeof(TypeA)); }
            for (int m = 0;
                 m < self.size[0];
                 m++) {
                D[idxD] = C[m];
                ++idxD;
            }
        });
        free(C);
    }

}

- (void)_load_miUINT8_mxDOUBLE_fromOperation:(vMAT_MATv5ReadOperation *)operation;
{
    loadFromOperation(self, operation, UINT8, DOUBLE);
}

私の質問は、「なぜ?」で終わるコメントから明らかなように、なぜconstここで宣言が必要なのですか? SwapA(...)省略されている場合、コンパイラは、 の本体に呼び出しサイト に一致するメソッド シグネチャがないことを報告しloadFromOperationます。

SwapAとして明示的に宣言されていれば、これは理解できますconstが、そうではありません。その操作は状態の変更に依存していないため、明らかにそうである可能性がありますが、それは重要ではありません。

また、このコードには別の有益な視点がありますが、より熟練した C++ 実践者が提供したいと考えているスタイルやその他の批評を歓迎します…</p>

4

1 に答える 1

3

ブロックによってキャプチャされた非__block変数は、ブロックの作成時に値によってブロックにコピーされ、ブロックconst内にあります。つまり、ブロック内でSwapAは、タイプがconst swapbytes<TypeA>.

于 2013-04-04T22:18:03.737 に答える