Я вынужден работать с API-интерфейсом C, который определяет набор кода, очень похожий на приведенный ниже
// Some old obscure c api
// First bunch of class in namespace ns
struct _ns_A { int a; };
struct _ns_AResponse { int resp; };
// Second bunch of classes in another ns
struct _ns2_B { int b; };
struct _ns2_BResponse { int resp; };
// Lots more classes in more namespaces...
// Bunch of parsing classes in namespace ns
_ns_AResponse* parse_A(_ns_A* a)
{
// do some work
return new _ns_AResponse { a->a * 100 };
}
// Parsing class in another ns
_ns2_BResponse* parse_B(_ns2_B* b)
{
// do some work
return new _ns2_BResponse { b->b * 100 };
}
// And so on....
Создает функцию анализа, названную для каждого отдельного пространства имен и типа, вместо использования перегруженных функций. Это также заставляет код клиента управлять памятью.
Чтобы помочь в этом, я написал код, похожий на:
// EXAMPLE Expansion: std::unique_ptr<_ns_AResponse> parse(_ns_A* a) { auto ret = parse_A(a); return std::unique_ptr<_ns_AResponse>(ret); }
#define REGISTER_INVOKER(NS, TYPE) inline std::unique_ptr<_##NS##_##TYPE##Response> parse(_##NS##_##TYPE* t) \
{ auto ret = parse_##TYPE(t); return std::unique_ptr<_##NS##_##TYPE##Response>(ret); }
// Register a single parse function for each of our types, stipulating namespace and class
REGISTER_INVOKER(ns, A);
REGISTER_INVOKER(ns2, B);
REGISTER_INVOKER(for 1000s of other types)
int main()
{
// Invoke our parse method with our unique_ptr to _ns_A
auto a = std::make_unique<_ns_A>();
auto a_ret = parse(a.get());
// And so on...
auto b = std::make_unique<_ns2_B>();
auto b_ret = parse(b.get());
}
Вышеприведенное позволяет нам иметь один вызов синтаксического анализа, который не только управляет использованием памяти для нас, но и перегружен по типу, что позволяет нам использовать его более ориентированным на c ++ способом.
У меня следующий вопрос:
Есть ли более подходящий способ сделать это, не прибегая к использованию макросов? У меня есть полное использование C ++ 17, а также повышение. Я бы предпочел не загрязнять нашу кодовую базу макросами, если меня не заставят.