在C++中将目标 C "code blocks"转换为等效值
Convert Objective C "code blocks" to equivalent in C++
我需要一个帮助转换一些Objective C "代码块"的方法等效于c++。请建议。
A被用作代码块…
定义在.h
文件..
typedef void (^A)(void*); //argument is ptr to B
在一个.mm
文件中使用…
[[hello getInstance] getB]->queueLoadImageWithBlock([self.str UTF8String], (A
) ^ (void * img){//一些代码…
});
最直接的类比是std::function
。这是一个被赋予签名的值类型(例如std::function<int(int)>
),并且可以是具有适当签名的任何函数对象。可以使用lambda来代替调用处的块。
obj->queueLoadImageWithBlock(self.url, [](void* img)
{
UIImage* img2 = (UIImage*)img;
UIImageView* iv = [[UIImageView alloc] initWithImage:img2];
iv.backgroundColor = [UIColor clearColor];
[self.iconSlot addSubview:iv];
iconLoaded(iv);
[iv release];
});
在Apple版本的clang中,您可以在C和c++以及Objective-C中使用块。显然,这是一个非标准的c++,但它可以工作。
你可以使用c++ lambdas而不改变被调用的函数,因为lambdas可分配给块(但不能反过来)。
只要对块的需求是您的,而不是系统的。
就像我说的,有几种方法。函数指针需要最少的样板文件,但它们需要一个额外的参数来传递来自调用者的上下文(在您的例子中是self
)。函子和指向成员的指针通常需要模板机制才能工作,我们就不一一讨论了。对于函数指针,应该是这样的:
//Let's define a callback datatype
typedef void (*ResourceLoadObjFuncPtr)(void *, void*);
//argument 1 is ptr to ResourceLoadDescriptor, argument 2 is iconSlot, whatever it is
//Function that implements that type:
void MyLoad(void *img, void *iconSlot)
{
UIImage* img2 = (UIImage*)img;
UIImageView* iv = [[UIImageView alloc] initWithImage:img2];
iv.backgroundColor = [UIColor clearColor];
[(TheTypeOfIconslot*)iconSlot addSubview:iv];
iconLoaded(iv);
[iv release];
}
并且您必须修改queueLoadImageWithBlock
的原型以接受ResourceLoadObjFuncPtr
参数而不是ResourceLoadObjCBlockCB
,以及上下文的另一个参数(在我们的示例中仅为iconSlot
)。
和调用:
[[GameViewController getInstance] getResourceLoadMediator]->
queueLoadImageWithFunction([self.url UTF8String], MyLoad, self.iconSlot);
块是闭包——它们捕获了声明它们的函数的变量。c++不提供iOS上GCC支持的闭包(除了块)。因此,您必须手动将变量从函数作用域传递给函数参数。在我们的例子中,如果我的假设是正确的,只有一个变量;在更复杂的情况下,你必须把它们包装在一个结构体中,并传递一个指向结构体的指针。
另一种方法是使用抽象基类和通过构造函数捕获上下文的具体实现。就像这样:
//Callback type
class ResourceLoader
{
public:
virtual void Load(void *) = 0;
};
//A callback implementation - not a function, but a class
class MyResourceLoader : public ResourceLoader
{
IconSlotType *iconSlot;
void Load(void *img)
{
//Same loader stuff as above
}
public:
MyResourceLoader(IconSlotType *isl)
:iconSlot(isl)
{}
};
对应的queueLoadImageWithBlock
现在将接受第二个类型为ResourceLoader*
的形参,而不接受第三个形参。至于调用,存在回调对象生命周期的问题。queueLoadImageWithBlock
是异步的-也就是说,它在调用回调之前返回吗?如果是这样,那么MyResourceLoader的本地实例将不起作用,您必须动态创建一个并以某种方式处理它。假设它是同步的(即在返回后不调用回调):
MyResourceLoader ResLoader(self.iconSlot);
[[GameViewController getInstance] getResourceLoadMediator]->
queueLoadImageWithLoader([self.url UTF8String], &ResLoader);
如果不是:
[[GameViewController getInstance] getResourceLoadMediator]->
queueLoadImageWithLoader([self.url UTF8String], new MyResourceLoader(self.iconSlot));
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 在C++中将目标 C "code blocks"转换为等效值