Reputation: 887
I'm working through Advanced Mac OS X Programming book and one exercise has me stumbled.
Use typedefs to simplify the following block reference declaration:
int (^(*(^get_block_factory_funcptr)(void))(int))(void);
Here's how I understand the declaration:
Function not taking arguments, returns a block which returns a void pointer, which is a pointer to a function that takes int for an argument and returns a block which has no arguments, returns an int.
Now given that, I have these 2 typedefs
typedef void *(^get_block_factory_funcptr)(void);
typedef int (^myBlock(int))(void);
However I have no idea how to combine them to a single declaration, any help appreciated
Upvotes: 1
Views: 52
Reputation: 25619
If I'm reading it correctly, it's a block that returns a function pointer that returns a block. The name is a hint.
One way to figure it out is to start with the end result and work backwards. Or, start from the inside and work outwards.
What is get_block_factory_funcptr
? It's a block:
MyBlock get_block_factory_funcptr;
What does it do? It takes a void and it returns a "Block Factory" function pointer. Let's declare MyBlock
:
typedef FactoryFuncPtr (^MyBlock)(void);
What is FactoryFuncPtr
? It takes an int
and returns another block:
typedef OuterBlock (*FactoryFuncPtr)(int);
What is OuterBlock
? It takes a void
and returns an int
:
typedef int (^OuterBlock)(void);
Those are the declarations in reverse order.
Edit: A working example.
#import <Foundation/Foundation.h>
typedef int (^OuterBlock)(void);
typedef OuterBlock (*FactoryFuncPtr)(int);
typedef FactoryFuncPtr (^MyBlock)(void);
OuterBlock factory(int foo) {
return ^ {
printf("A block with %d\n", foo);
return 123;
};
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
int (^(*(^get_block_factory_funcptr)(void))(int))(void) = ^ {
return &factory;
};
MyBlock myBlock = get_block_factory_funcptr;
FactoryFuncPtr foo = myBlock();
OuterBlock bar = foo(999);
int baz = bar();
printf("Final %d\n", baz);
}
return 0;
}
Upvotes: 2