[英]Default argument vs std::optional as an argument vs Function Overloading
假设我要实现一个函数func
。
func
。 func
将仅使用一个参数来调用,但是该函数中将使用缺少的第二个参数的默认值。 我可以想到三种实现此功能的方法:
void func(int a, long b = c);
func
将被这样调用:
func(a);
func(a, b);
void func(int a);
void func(int a, long b);
func
将被这样调用:
func(a);
func(a, b);
void func(int a, optional<long> b);
func
将被这样调用:
func(a, optional<long> ());
func(a, b);
我想知道实现所需功能的最佳方法是什么。 欢迎任何建议。
在考虑这一点时,有两个问题要问自己:
如果第二个参数具有逻辑默认值,并且该函数不管做什么都执行相同的操作,则默认参数可以正常工作。 例如:
std::vector<std::string> split_string(const std::string& str, char sep = ' ');
默认情况下,这会在空格处分割字符串,但是可以使用分隔符来更改它。 将其分为两个重载或在此处使用std::optional
几乎没有意义。
如果第二个参数没有逻辑默认值,但是如果没有给出该函数,则该函数仍基本相同,则std::optional
更具意义。 例如:
void extract(const std::filesystem::path& archive_file,
const std::filesystem::path& output_dir,
std::optional<std::regex> exclude_filter = {});
在这里,我们从存档文件中提取文件,并将提取的文件写入磁盘,还可以选择排除与某些模式匹配的文件。 使用或不使用过滤器,函数定义在根本上是相同的; 这只是一个额外的区别:
if (exclude_filter && std::regex_match(file, *exclude_filter) continue;
复制定义没有多大意义,因此重载实际上没有任何意义。 同时,没有“不匹配任何内容”的正则表达式,因此没有可以应用的逻辑默认过滤器。 std::optional
非常适合这里。
请注意,我仍然使用默认参数。 将您的std::optional
缺省设置为空可以使您的调用更好。
最后,如果函数的实现在one-arg和two-arg版本之间根本不同,则请使用重载。 例如:
void hide(window& win) {
win.set_visible(false);
}
template <typename rep, typename period>
void hide(window& win, const std::chrono::duration<rep, period>& fade_time) {
auto wait_time = equal_intervals(fade_time, win.opacity());
while (win.oapcity() > 0) {
win.set_opacity(win.opacity() - 1);
std::this_thread::sleep_for(wait_time);
}
}
在这里,我们隐藏了具有可选淡出时间的窗口。 尽管这些函数在逻辑上执行相同的操作,但实现方式却完全不同。 具有相同的功能没有多大意义。 尽管0
是逻辑上的默认淡入时间,但在此处使用默认参数仍然没有意义,因为您最终会得到一个很大的if
块:
if (fade_time == 0) {
// body of the first overload
} else {
// body of the second overload
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.