C++ optional 实战:区分零平均值与没有结果
封装平均值函数,用 optional 显式表达空集合没有结果,练习 const 引用、浮点转换和取值前的分支检查。
本节目标
封装平均值函数,用 optional 显式表达空集合没有结果,练习 const 引用、浮点转换和取值前的分支检查。
环境与运行方法
使用 C++17 编译器,保存为 lesson.cpp,执行 c++ -std=c++17 -Wall -Wextra -Werror lesson.cpp -o lesson 后运行 ./lesson。以下仅使用标准库。
核心思路
空集合没有通常意义上的算术平均值,返回零会与真实全零记录混淆。optional<double> 将有值与无值写入返回类型,让调用方根据存在性处理结果。
完整示例
#include <iostream>
#include <vector>
#include <optional>
std::optional<double> average(const std::vector<int>& values) {
if (values.empty()) return std::nullopt;
long total = 0;
for (int value : values) total += value;
return static_cast<double>(total) / values.size();
}
int main() {
auto result = average({20, 40});
if (result) std::cout << "average=" << *result << '\n';
auto empty = average({});
std::cout << "empty=" << (empty ? "value" : "none") << '\n';
}预期输出
average=30
empty=none逐步理解
const 引用读取原集合而不复制整个 vector;nullopt 表达没有数值。调用者先判断 optional,再解引用。平均值即使为零,optional 仍然有值,不能用内部数字的真假代替存在性检查。
转换在除法前发生,从而保留小数。本函数计算全部整数,没有沿用前文过滤负值的规则。复用函数时应阅读契约,而不是凭相近名称推断数据清洗逻辑。
常见问题与边界
- 不检查直接解引用会破坏空结果处理。
- 不能返回局部变量的引用。
- optional 不会自动检查数值范围或业务合理性。
动手练习
分别传入 {0,0}、{1,2} 和空集合。
参考答案
结果分别为有值 0、有值 1.5、无值。三个分支揭示“没有结果”和“结果为零”之间的区别。
文章回复
0 条公开回复