ITPub博客

首页 > 数据库 > 数据库开发技术 > 国外C++程序员分享:多值返回技巧,你不能忽视的精彩秘籍

国外C++程序员分享:多值返回技巧,你不能忽视的精彩秘籍

原创 数据库开发技术 作者:讳疾忌医-note 时间:2025-02-05 07:37:52 0 删除 编辑
创作不易,方便的话点点关注,谢谢
本文是经过严格查阅相关权威文献和资料,形成的专业的可靠的内容。全文数据都有据可依,可回溯。特别申明:数据和资料已获得授权。本文内容,不涉及任何偏颇观点,用中立态度客观事实描述事情本身。

文章结尾有最新热度的文章,感兴趣的可以去看看。

文章有点长(2169字阅读时长:5分),期望您能坚持看完,并有所收获


大家好,今天我继续给大家分享干货。熟悉我的人,都知道我真正的干货一般在中间和末尾部分(文章中间部分:有项目文字和视频介绍)。请耐心看完!谢谢。您可以在文章末尾处获取完整的源代码文件。

 

今天,咱们来探讨一个经典的面试问题:一个函数如何返回多个结果呢?你能想出几种方法?

实际上,这个问题涵盖了众多知识点,其中包括:

  • • 指针
  • • 引用
  • • Lambda 表达式
  • • 函数式编程
  • • std::tie
  • • std::tuple
  • • 结构化绑定
  • • 模板推导
    等等

本文将探究回答这个问题的不同方法。首先,咱们把问题具体化,以 a / b 为例(暂不考虑除数为零的情况),要同时返回商和余数。简单来说,我们有多少种方式可以编写一个能同时返回商和余数的函数呢?

现在,让我们深入探讨具体内容。

1. 指针和引用

通过添加两个变量并使用指针和引用来修改函数接口。

void divideWithReferences(int dividend, int divisor, int& quotient, int& remainder) {
  quotient = dividend / divisor;
  remainder = dividend % divisor;
}

void divideWithPointers(int dividend, int divisor, int* quotient, int* remainder) {
  if (quotient) *quotient = dividend / divisor;
  if (remainder) *remainder = dividend % divisor;
}

这种方法的缺点很明显,当返回值超过两个时,函数接口会变得冗长。此外,如果面试官禁止修改函数接口,这种方法就不可行了。

2. 元组(Tuple) + 解包绑定(Tie)

std::tuple 和 std::tie 的组合提供了一种简洁的方式,可从函数中返回多个值。通过使用 std::tie,我们可以将元组的元素解包到不同的变量中,从而提高代码的清晰度。

这种方法被认为是标准答案之一,既简单又清晰。它在返回两个值时也同样适用。

std::tuple<int, int> divide(int dividend, int divisor) {
  return std::make_tuple(dividend / divisor, dividend % divisor);
}

int quotient, remainder;
std::tie(quotient, remainder) = divide(14, 3);
std::cout << quotient << ", " << remainder << std::endl;

3. 结构化绑定

在前面方法的基础上,C++17 引入了结构化绑定,进一步简化了多值返回的代码。使用 auto 和结构化绑定能让代码更加直观。

如果面试官要求对前面的方法进行进一步优化,可以将代码转换为以下示例,使用结构化绑定让代码结构更优雅。

auto divide(int dividend, int divisor) {
  struct result {
    int quotient;
    int remainder;
  };
  return result{dividend / divisor, dividend % divisor};
}
auto [quotient, remainder] = divide(14, 3);

4. 函数回调

在日常项目,尤其是开源项目中,回调是一种常用的机制。通过传递一个处理返回值的回调函数,用户可以自定义处理方式,使代码结构更加灵活。这在异步编程和事件处理等场景中特别有用。

void divide(int dividend, int divisor, std::function<void(int, int)> callback) {
  callback(dividend / divisor, dividend % divisor);
}

5. 自定义输出封装

自定义输出封装是将输出参数封装在一个结构体中的方法。这种方法提高了代码的可读性,尤其适用于需要返回多个值的函数。

template <class T>
struct out {
  std::function<void(T)> target;

  out(T* t)
      : target([t](T&& in) {
          if (t) *t = std::move(in);
        }) {}
  template <class... Args>
  void emplace(Args&&... args) {
    target(T(std::forward<Args>(args)...));
  }
  template <class X>
  void operator=(X&& x) {
    emplace(std::forward<X>(x));
  }
  template <class... Args>
  void operator()(Args&&... args) {
    emplace(std::forward<Args>(args)...);
  }
};

void divide(int dividend, int divisor, out<int>& quotient_out, out<int>& remainder_out) {  
    quotient_out.emplace(dividend / divisor);
  remainder_out.emplace(dividend % divisor);
}

6. 模板推导

C++ 的模板推导为开发者提供了一种更灵活、简洁的代码编写方式。通过模板推导,我们可以处理不同的数据类型,而无需显式指定它们。

template <typename T1, typename T2>
struct many {
  T1 quotient;
  T2 remainder;
};

template <class T1, class T2>
many(T1, T2) -> many<T1, T2>;

many<int, int> divide(int dividend, int divisor) {
  return many{
      dividend / divisor,
      dividend % divisor,
  };
}

auto [quotient, remainder] = divide(14, 3);

综上所述,C++ 提供了多种实现多值返回的方法,每种方法都有其适用的场景。方法的选择取决于具体需求,开发者可以根据代码结构和可读性灵活运用这些特性。以上就是我的分享。这些分析皆源自我的个人经验,希望上面分享的这些东西对大家有帮助,感谢大家!

 

参考文献

Stroustrup, Bjarne. 《The C++ Programming Language》

ISO/IEC 14882:2017 《Programming Language C++》

Meyers, Scott. 《Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14》

 

点个“在看”不失联

最新热门文章推荐:

C++函数式编程:那些你不容错过的精彩技巧

借助C++OpenCV图像背景替换:老办法束手无策,新方案如何出奇制胜?

DeepSeek优势探秘:传统训练成本高,它如何凭优势改写大模型发展走向?

从无名到C++大神,赫布·萨特(Herb Sutter)如何逆袭?

C++游戏开发:传统贪吃蛇,如何玩出新花样?

告别传统拜年,C++ncurses库终端拜年程序

C++OpenCV实现实时模板匹配算法:老办法匹配已过气,实时识别有何高招?

C++OpenCV实时二维码识别:传统扫码已过时,实时捕捉有何奇招?

C++ OpenCV图像增强:模糊图片成过去,高清蜕变有何妙招?

C++OpenCV手指调音量:传统操作已 out,新解法如何脱颖而出?

C++OpenCV手指检测:为何开发者纷纷放弃传统,拥抱高效新解法

C++OpenCV实现车道偏离检测:为何开发者摒弃复杂监测,采用高效的视觉解决方案

C++OpenCV实现人脸识别:为何开发者正在抛弃旧技术,拥抱CV新解法

 以上就是我的分享。这些分析皆源自我的个人经验,希望上面分享的这些东西对大家有帮助,感谢大家!

文章中源代码怎么获取:关注官方微信公众号,就可以获取。

原文作者:讳疾忌医-note;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2024-08-12

  • 博文量
    126
  • 访问量
    73110