我发现赋值块在Objective-C类参数和C++类参数方面的行为不同。分配块指针:Objective-C和C++类之间的区别
想象我有这个简单的Objective-C类层次结构:
@interface Fruit : NSObject
@end
@interface Apple : Fruit
@end
然后,我可以写这样的东西:
Fruit *(^getFruit)();
Apple *(^getApple)();
getFruit = getApple;
这意味着,对于Objective-C类 ,块返回类型为协变:返回更具体的东西的块可以看作是返回更一般东西的块的“子类”。在这里,提供苹果的getApple
块可以安全地分配给getFruit
块。事实上,如果以后使用,当您预计Fruit *
时,它总是保存为接收Apple *
。而且,从逻辑上讲,逆向不起作用:getApple = getFruit;
不能编译,因为当我们真的想要一个苹果时,我们并不开心得到一个水果。
同样,我可以写:
void (^eatFruit)(Fruit *);
void (^eatApple)(Apple *);
eatApple = eatFruit;
这表明块在它们的参数类型协变:能够处理一个参数,更一般的,可以使用一个块,其中一个块的过程需要更具体的论点。如果一个街区知道如何吃水果,它也会知道如何吃苹果。再一次,反过来是不正确的,这不会编译:eatFruit = eatApple;
。
这是一切都很好,在Objective-C中。现在让我们尝试在C++或Objective-C++,假设我们有这些类似的C++类:
class FruitCpp {};
class AppleCpp : public FruitCpp {};
class OrangeCpp : public FruitCpp {};
可悲的是,这些块分配,不进行编译更多:
FruitCpp *(^getFruitCpp)();
AppleCpp *(^getAppleCpp)();
getFruitCpp = getAppleCpp; // error!
void (^eatFruitCpp)(FruitCpp *);
void (^eatAppleCpp)(AppleCpp *);
eatAppleCpp = eatFruitCpp; // error!
锵抱怨与“从不兼容的类型分配“错误。所以,相对于C++类,块看起来是不变的返回类型和参数类型。
这是为什么?我对Objective-C类所做的论述是否也适用于C++类?我错过了什么?
最有可能的是,该功能被忽略了。有[提交](http://llvm.org/viewvc/llvm-project?view=revision&revision=125445)显示铿锵人关心在Objective-C类型的Objective-C++中为协变和逆变工作,但我不能'为C++本身找到任何东西。 [语言规范块](http://clang.llvm.org/docs/BlockLanguageSpec.html)也没有提及。 – zneak 2013-03-09 16:18:14
我应该把它作为一个错误/功能请求放在什么地方? – 2013-03-09 16:23:04
您可以提交LLVM项目的错误和功能请求[此处](http://llvm.org/bugs/enter_bug.cgi)(需要使用有效的电子邮件进行免费注册,就像大多数公众的错误跟踪程序一样),但希望延迟至少有几个月的时间。如果你真的了解它,如果你想自己制作补丁,邮件列表上的人可能会很乐意协助你。 – zneak 2013-03-09 16:46:10