templates - 为什么这个仿函数的operator()需要尾随const修饰符?

标签 templates objective-c-blocks objective-c++ functor vmat

在离开多年之后,我又回到了 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 声明?如果省略它,编译器会提示 loadFromOperation 正文中的 SwapA(...) 处没有与调用站点匹配的方法签名。

如果将 SwapA 显式声明为 const,我会理解这一点,但事实并非如此。显然它可能是,因为它的操作不依赖于改变任何状态,但这不是重点。

虽然我对这段代码有另一双有用的眼睛,但我欢迎更熟练的 C++ 从业者可能愿意提供的任何风格或其他批评......

最佳答案

非-__block block 捕获的变量在创建 block 时按值复制到 block 中,并且是 const block 内。即在 block 内,SwapA类型为 const swapbytes<TypeA> .

关于templates - 为什么这个仿函数的operator()需要尾随const修饰符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15819151/

相关文章:

ios - 使用适用于 iOS 的 OpenCV 框架的 Apple Mach-O Linker (Id) 错误

c++ - 使用 C++ 模板的数据映射器设计模式

c++ - 有没有更好的方法从静态和非静态函数返回相同的字符串文字?

C++ - 在模板类之外但在头文件中定义成员函数

iOS - 在使用成功 block 进行异步网络调用时查看 Controller 内存管理

objective-c - "__block"关键字是什么意思?

objective-c - msg_send 调用会产生多少开销?

Xcode Objective C++——避免制作 .hh 文件?

objective-c - 如何在 objective-c++ 中编译特定文件以及在 objective-c 中编译项目的其余部分

c++ - 模板类函数 T : How to find out if T is a pointer?