我正在尝试改善代码风格。
有时,我有一些方法可以执行复杂的检查或计算,并且根据调用方法的上下文,我需要与这些算法不同的结果。假设有一个结果,它总是需要的,它将是方法的返回值。但是如何处理可选的其他结果呢?当然,我只想实现我的复杂方法一次。因此,我介绍了可修改的参考参数,并根据某些条件将其替换为这些附加结果。
为方便我不需要其他结果的环境,我引入了重载,这些重载创建了将传递给单个实现的虚拟变量。
请参见以下简化的示例代码:
#include <iostream>
/**
* \brief Checks whether everything is okay.
*
* \param isCheckedFirstTime if point is not null, it will be overwritten with
* whether this method has been called for the first time
*
* \returns okay or not
*/
bool isOkay(bool*& isCheckedFirstTime)
{
static bool isFirstTime = true;
if (nullptr != isCheckedFirstTime)
{
*isCheckedFirstTime = isFirstTime;
}
isFirstTime = false;
return true;
}
/**
* \brief Checks whether everything is okay.
*
* \returns okay or not
*/
bool isOkay()
{
bool* dummy = nullptr;
return isOkay(dummy);
}
int main()
{
const bool okay = isOkay();
std::cout << "Is everything okay?: " << okay << std::endl;
return 0;
}
显然,可以通过像这样添加参数isCheckedFirstTime
的默认值来摆脱很多样板代码
bool isOkay(bool*& isCheckedFirstTime = nullptr)
这是不合法的,因为我无法将非常量左值引用绑定到相应类型的右值。
是否有解决方法?还是有另一种可能,就是只有一种方法可以进行所有计算而不会对不同的输出进行重载,并且无需,而不必在调用代码中声明伪参数?
我想到的一种解决方案是将所有可能的结果打包到一个std::tuple
中。然后,呼叫者可以使用他想要的东西。但是,如果计算可选结果的成本很高,则可能会有一个缺点。如果没有人需要结果,那么有了条件(例如nullptr != ...
)可以节省计算时间。
我期待着您的建议!
答案 0 :(得分:2)
通常,这是通过返回std::tuple
来完成的。
在您的情况下,它将类似于:
std::tuple<bool,bool> isOkay()
{
static bool isFirstTime = true;
bool isCheckedFirstTime = isFirstTime;
isFirstTime = false;
return std::make_tuple(true, isCheckedFirstTime);
}
如果需要返回可选的复杂对象,或者不想计算不需要的值,则可以使用C ++ 17最好使用std::optional
。
std::tuple<bool,std::optional<bool>> isOkay(bool needCheckFirstTime = false)
{
static bool isFirstTime = true;
std::optional<bool> isCheckedFirstTime;
if (needCheckFirstTime) {
isCheckedFirstTime = isFirstTime;
}
isFirstTime = false;
return std::make_tuple(true, isCheckedFirstTime);
}
答案 1 :(得分:1)
您似乎不确定isCheckedFirstTime
是指针还是引用,因此您同时做到了。只是不方便。
这可能更具表现力:
bool isOkay(std::optional<bool>& isCheckedFirstTime)
{
static bool isFirstTime = true;
if (isCheckedFirstTime)
{
*isCheckedFirstTime = isFirstTime;
}
isFirstTime = false;
return true;
}
bool isOkay()
{
std::optional<bool> dummy;
return isOkay(dummy);
}
答案 2 :(得分:1)
因此,我介绍了可修改的参考参数,根据某些条件,它们会被这些附加结果覆盖。
避免像瘟疫一样使用掉参数。如果函数产生结果,则它应该是其返回类型的一部分。那么我们如何找出适合您情况的类型?
您已经建议了一个元组;在这种情况下,struct
或元组会很好地工作。
但是,如果计算可选结果的成本很高,则可能会有不利之处。
当然可以,但是没有任何内容表明您必须将参数绑定到结果上。函数可以使用一个位集或类似的枚举,告诉其确切要计算什么,并返回一个充满optional
值的结构。具体情况将在很大程度上取决于要解决的具体情况。