Возвращение данных произвольных простых типов из функции - PullRequest
0 голосов
/ 26 октября 2018

Я обновляю некоторый существующий код C ++, который датируется около 25 лет.В коде есть ряд функций типа «применить функцию к коллекции» с сигнатурами, такими как

void *CNode::DoUntil(CNode *aRoot, TestFunc1 aFunc, void *aParam)

, где aFunc имеет сигнатуру

void *(*TestFunc1)(CNode *xNode, void *xParam)

Это относится aFunc ккаждый элемент в коллекции, пока aFunc не вернет ненулевое значение.В большинстве случаев это используется для создания таких операций, как «find», которые возвращают указатель на найденный объект, но иногда это такие операции, как «count», где целое число вставляется в возвращаемое значение void * и вытягиваетсяобратно назад вызывающим абонентом.Излишне говорить, что это 1) безобразно и 2) вызывает крики компиляторов.Например:

dataItemID = (itemID)CNode::DoUntil(getDatabase(), FindItemFuncPtr, &data)

выдает ошибку cast from pointer to smaller type 'itemID' (aka 'unsigned int') loses information.

Что является подходящим идиоматическим способом возврата данных произвольного типа из функции в этой ситуации?Как минимум, он должен поддерживать целые числа, логические значения и указатели, и из-за используемого мной компилятора он не может использовать конструкции, более новые, чем C ++ 11.

Я не хочусделать большую переписать код;в идеале я бы просто изменил задействованные функции, чтобы получить std::any, но это часть C ++ 17, а не C ++ 11.

1 Ответ

0 голосов
/ 26 октября 2018

Не уверен, если это слишком много изменений, но я бы пошел на что-то вроде:

enum class EIterationStep
{
    Break,
    Continue
};

enum class EIterationStatus 
{
    Interrupted,
    Finished
};

EIterationStatus CNode::DoUntil(CNode *aRoot, std::function<EIterationStep(CNode *)> func);

Я предполагаю, что ввод void* это пользовательские данные, которые теперь могут быть захвачены в лямбда / функтор,Вы можете изменить enum на bool с правильным соглашением (и, возможно, на void для DoUntil, если результат не используется).

Вы можете передать захват лямбды, чтобы обновить count или найденный элемент.

Я бы изменил указатель по ссылке, если это возможно.

Вы можете изменить std::function по шаблону, если хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...