c++ - 通用“sqr”函数
问题描述
我试图弄清楚如何为 sqr 操作编写“完全通用的函数”(它实际上可以是乘法、除法、加法,并不重要)。
考虑以下代码
#include <iostream>
struct A
{
int val = 2;
A() = default;
A(const A&) = delete; // To make sure we do not copy anything
A(A&& a) = delete; // To make sure we do not move anything
auto operator=(auto) = delete; // To make sure we do not assign anything
// This is important part, we do not want to create a new object on each multiplication.
// We want just to update the old one.
A& operator*(const A& a)
{
val *= a.val;
return *this;
}
};
// Just for easy printing (you can ignore it).
std::ostream &operator<<(std::ostream &os, const A& a) {
return os << a.val;
}
// Here auto&& represents forwarding reference and should automatically understand whether input r or l value.
auto&& sqr(auto&& val)
{
return val * val;
}
int main()
{
A a;
std::cout << sqr(a) << "\n"; // OK
std::cout << sqr(A()) << "\n"; // OK
std::cout << sqr(1) << "\n"; // Wrong, ref to local returned
int i = 2;
std::cout << sqr(i) << "\n"; // Wrong, ref to local returned
}
sqr
这里的函数是一种通用的东西,它应该处理所有可能的情况(r-values,l-values)并且对于 objecta
它实际上是这样做的,但不是对于i
. 我不明白为什么它试图返回参考而不是复制。有人可以说明情况吗?有什么方法可以轻松完成这项任务(理想情况下使用一个模板函数)?如有必要,我可以使用 c++ 20 标准。
解决方案
auto&& sqr(auto&& val)
{
return val * val;
}
sqr
上面总是返回一个引用。但是返回对本地的引用总是错误的。让返回类型通过使用来推断为非引用auto
。
auto sqr(auto&& x) // return type is non-reference or trailing
noexcept(noexcept(x*x)) // propagate noexcept
-> decltype(x*x) // enable SFINAE
{ return x * x; }
推荐阅读
- go - 如何在运行时添加命令,或定义未知命令的行为?
- python - 不确定如何从字符串中删除空格
- c - srand() 和 rand() 的 C 替换
- c# - 在 UserControl 错误面板转换中从 Parent-Form 设置字符串
- r-exams - 为 schoice 或 mchoice 问题生成 html 或 docx 答案键
- ffmpeg - 使用未压缩格式录制,以便使用 ffmpeg 更快地进行切割
- javascript - Bootstrap Modal:使正文内容全宽模态
- python-3.x - 使用 python selenium 无法找到浏览器中显示的文本
- flutter - 由于 XCode,通用链接在 Flutter 中的 iOS 上不起作用
- django - 如何将登录用户的 id 传递给 CreateView