我正在更新一些可以追溯到25年的现有C ++代码。该代码具有许多带有签名的“将函数应用于集合”类型的函数,例如
void *CNode::DoUntil(CNode *aRoot, TestFunc1 aFunc, void *aParam)
其中aFunc
具有签名
void *(*TestFunc1)(CNode *xNode, void *xParam)
这将aFunc
应用于集合中的每个项目,直到aFunc
返回非NULL为止。在大多数情况下,它用于产生“ 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。
答案 0 :(得分:0)
不确定是否有太多更改,但我会选择:
enum class EIterationStep
{
Break,
Continue
};
enum class EIterationStatus
{
Interrupted,
Finished
};
EIterationStatus CNode::DoUntil(CNode *aRoot, std::function<EIterationStep(CNode *)> func);
我假设输入void*
是用户数据,现在可以在lambda / functor中捕获该数据。
您可以使用正确的约定通过bool
来更改枚举(如果不使用结果,可以通过void
来更改DoUntil
的枚举)。
您可以传递捕获的lambda来更新count
或找到的项目。
如果可能,我将通过引用更改指针。
如果需要,可以按模板更改std::function
。