Компилятор Objective-C++ принимает несколько аргументов сообщения для синтаксиса C++ лямбда?
Следующее должно быть легальным Objective-C++, насколько я могу судить. Но это не компилируется:
/*
* compile:
*
* gcc -c $(gnustep-config --objc-flags) -x objective-c++
*
* fails for gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.1)
*
* works with -DNO_SECOND or -x objective-c
*/
#import <Foundation/Foundation.h>
/*
* if defined, use only one argument
*/
#ifdef NO_SECOND
# define X(_)
#else
# define X(_) _
#endif
@interface Foo : NSObject
@end
@implementation Foo : NSObject
int a0, a1;
-(id)initWith: (int)a0_in X(: (int)a1_in) {
a0 = a0_in;
X(a1 = a1_in;)
return [super init];
}
-(int)a0 {return a0;}
X(-(int)a1 {return a1;})
@end
int main() {
int a0 = 0;
X(int a1 = 1;)
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id bar = [Foo alloc];
bar = [bar initWith:a0 X(:a1)];
NSLog(@"%i", [bar a0]);
X(NSLog(@"%i", [bar a1]);)
[pool drain];
return 0;
}
Проблема, кажется, в сообщении initWith
отправлено bar
, Компилятор жалуется:
m.mm: In function ‘int main()’:
m.mm:46:27: error: found ‘:’ in nested-name-specifier, expected ‘::’
bar = [bar initWith:a0 X(:a1)];
^
m.mm:24:15: note: in definition of macro ‘X’
# define X(_) _
^
m.mm:46:22: warning: no ‘-initWith:’ method found
bar = [bar initWith:a0 X(:a1)];
^
m.mm:46:22: warning: (Messages without a matching method signature
m.mm:46:22: warning: will be assumed to return ‘id’ and accept
m.mm:46:22: warning: ‘...’ as arguments.)
m.mm:46:13: error: expected ‘,’ before ‘initWith’
bar = [bar initWith:a0 X(:a1)];
^
m.mm:46:13: error: ‘initWith’ was not declared in this scope
m.mm:46:21: error: expected ‘,’ before ‘:’ token
bar = [bar initWith:a0 X(:a1)];
^
m.mm:46:21: error: expected identifier before ‘:’ token
m.mm: In lambda function:
m.mm:46:32: error: expected ‘{’ before ‘;’ token
bar = [bar initWith:a0 X(:a1)];
^
m.mm: In function ‘int main()’:
m.mm:46:32: warning: lambda expressions only available with -std=c++11 or -std=gnu++11
m.mm:46:6: error: cannot convert ‘main()::<lambda()>’ to ‘objc_object*’ in assignment
bar = [bar initWith:a0 X(:a1)];
^
m.mm:43:8: warning: unused variable ‘a1’ [-Wunused-variable]
X(int a1 = 1;)
^
m.mm:24:15: note: in definition of macro ‘X’
# define X(_) _
^
Каким-то образом компилятор считает, что это лямбда-код C++. Однако код работает нормально, если initWith
имеет только один параметр (попробуйте это с помощью -DNO_SECOND
).
Обратите внимание, что этот код принимается как код Objective C: -x objective-c
, Связать с $(gnustep-config --base-libs)
, Беги и читай:
2016-08-05 10:59:36.251 m[21666] 0
2016-08-05 10:59:36.252 m[21666] 1
Что я делаю неправильно? Или Objective-C++ сломан и не исправит?