В чистом мире С++ мы можем генерировать код сопряжения или клей между различными компонентами или интерфейсами во время компиляции, используя комбинацию времени компиляции и времени выполнения на основе шаблонов (например, в основном, автоматически автоматически набирать/удалять вызовы с использованием устаревших типов).
При взаимодействии приложений на С++ с Objective-C/Cocoa для графического интерфейса пользователя, системной интеграции или IPC, тем не менее, все становится все труднее из-за менее строгой типизации - но часто не более, чем требуется плоский поверхностный слой интерфейса: тонкий должны быть определены мосты делегатов или должен быть написан код преобразования для переадресации вызовов.
Если вам приходится иметь дело с интерфейсами нетривиального размера и вы хотите избежать генерации кода на основе script, это быстро становится громоздким и является просто болью каждый раз, когда должны выполняться рефакторинги. Используя комбинацию метапрограммирования (шаблона) и библиотеки времени исполнения Objective-C, должно быть возможно значительно уменьшить количество кода...
Прежде чем я перейду заново изобретать колесо (и, возможно, тратить время), знает ли кто-нибудь о методах, лучших практиках или примерах в этом направлении?
Как для примера, скажем, нам нужен делегат, который поддерживает этот неофициальный протокол:
- (NSString*)concatString:(NSString*)s1 withString:(NSString*)s2;
- (NSNumber*) indexOf:(CustomClass*)obj;
Вместо того, чтобы теперь реализовать класс Obj-C, который явно переводит мосты в экземпляр С++, я хотел бы сделать что-то вроде этого:
class CppObj {
ObjcDelegate m_del;
public:
CppObj() : m_del(this)
{
m_del.addHandler
<NSString* (NSString*, NSString*)>
("concatString", &CppObj::concat);
m_del.addHandler
<NSNumber* (CustomClass*)>
("indexOf", &CppObj::indexOf);
}
std::string concat(const std::string& s1, const std::string& s2) {
return s1.append(s2);
}
size_t indexOf(const ConvertedCustomClass& obj) {
return 42;
}
};
Все, что нужно от пользователя для поддержки дополнительных типов, должно было бы специализировать функцию шаблона преобразования:
template<class To, class From> To convert(const From&);
template<>
NSString* convert<NSString*, std::string>(const std::string& s) {
// ...
}
// ...
Приведенный выше пример, конечно, игнорирует поддержку формальных протоколов и т.д., но должен иметь смысл. Кроме того, из-за информации типа для типов Objc-runtime, которые в основном разлагаются на некоторые-родные типы или типы классов, я не думаю, что можно избежать явной спецификации типов параметров и возвращаемых данных для методов-делегатов.