繁体   English   中英

默认参数vs std ::可选作为参数vs函数重载

[英]Default argument vs std::optional as an argument vs Function Overloading

假设我要实现一个函数func

  • 我有一个用例,其中将使用两个参数来调用func
  • 我还有另一个用例,其中func将仅使用一个参数来调用,但是该函数中将使用缺少的第二个参数的默认值。

我可以想到三种实现此功能的方法:

  1. 默认参数
void func(int a, long b = c);

func将被这样调用:

func(a);
func(a, b);
  1. 功能重载
void func(int a);
void func(int a, long b);

func将被这样调用:

func(a);
func(a, b);
  1. 使用Optional作为函数参数
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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM