使我的结构或类与std::round兼容
Make my struct or class compatible with std::round
给定以下内容,如何使我的类或结构与std::round兼容?(我认为同样的东西也会使它与std::floor和td::ceil一起使用)。我能做这个吗?
C++外壳版本
#include <cmath>
struct Rectangle
{
Rectangle(double _x1, double _x2, double _y1, double _y2) :
x1(_x1), y1(_y1), x2(_x2), y2(_y2)
{
}
double x1, y1, x2, y2;
};
int main(void )
{
auto r = Rectangle(10.3, 10.4, 10.5, 10.6);
r = std::round(r);
std::cout << r.x1 << "," << r.y1 << "," << r.x2 << "," << r.y2 << std::endl;
}
不能让std::round
这样做:它已经定义好了,也不能向命名空间std
中添加新的重载。
可以编写一个新函数并使用它(一个简单的函数或Tartan Llama显示的方法,但我更喜欢这里的免费函数)
Rectangle round(Rectangle const &original) {
return { std::round(original.x1), std::round(original.y1),
std::round(original.x2), std::round(original.y2) };
}
同样,将此添加到命名空间std是非法的。只要确保它与Rectangle
本身在同一个命名空间中,ADL就会为您找到它。
顺便说一句,让构造函数参数和它们对应的成员以不同的顺序排列在这里是令人困惑和容易出错的。在统一初始化和上面的显式构造函数之间切换需要更改参数顺序,但编译器无法发现这一点。
如果您想要一个函数来舍入Rectangle
的所有点并返回一个新的点,那么您自己编写它;尝试使用std::round
来实现这一点实际上没有意义。
一种选择:
struct Rectangle
{
Rectangle(double _x1, double _x2, double _y1, double _y2) :
x1(_x1), y1(_y1), x2(_x2), y2(_y2)
{ }
Rectangle round() {
return { std::round(x1), std::round(x2),
std::round(y1), std::round(y2) };
}
double x1, y1, x2, y2;
};
那就这样称呼它吧:
r = r.round();
用于讨论和思考:
我最初的想法是按照@Useless:-在与参数相同的命名空间中使用一个自由函数是正确的方法。
然而,更仔细地思考函数round
的推断语义给我提出了一个问题:
round
听起来更像是一个命令,而不是一个修饰符。我知道已经有一个std::round返回一个整型参数的副本,但还有一个std::sort
对对象进行适当排序。
在我看来,如果你想要一个四舍五入的副本,你可能想调用一个名为rounded
的函数,如果你想真正让一个对象自己四舍五舍五入,你可能想要调用它的round
如果你同意这个想法,代码会开始看起来像这样:
#include <cmath>
#include <iostream>
struct Rectangle
{
Rectangle(double _x1, double _x2, double _y1, double _y2)
: x1(_x1), y1(_y1), x2(_x2), y2(_y2)
{
}
Rectangle& round() {
using std::round;
x1 = round(x1);
y1 = round(y1);
x2 = round(x2);
y2 = round(y2);
return *this;
}
Rectangle& normalise()
{
// something here
return *this;
}
double x1, y1, x2, y2;
};
Rectangle rounded(Rectangle r)
{
return r.round();
}
Rectangle& round(Rectangle& r)
{
return r.round();
}
Rectangle normalised(Rectangle r)
{
return r.normalise();
}
Rectangle& normalise(Rectangle& r)
{
return r.normalise();
}
int main(void )
{
auto r = Rectangle(10.3, 10.4, 10.5, 10.6);
// take a rounded, normalised copy
auto r1 = rounded(normalised(r));
// take a rounded copy
auto r2 = rounded(r);
// take a copy
auto r3 = r;
// normalise and round the copy
normalise(round(r3));
round(r);
std::cout << r.x1 << "," << r.y1 << "," << r.x2 << "," << r.y2 << std::endl;
}
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 为什么 std::round(sin(pi/6)) 不等于 1?
- std::nearbyint vs std::round in C++11
- 从std::round转换为int是否安全
- "round"不是"std"的成员
- 使我的结构或类与std::round兼容
- 我应该在尝试使用std::round()时添加少量吗
- 是否可以强制"round"位于命名空间std中