鉴于以下内容,如何使我的类或结构与 std :: round 兼容? (我假设同样的事情也可以用于 std :: floor 和 std :: ceil )。我可以这样做吗?
#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;
}
答案 0 :(得分:5)
您无法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就会为您找到它。
顺便说一下 - 让你的构造函数参数和它们对应的成员对应的命令不同,这里容易引起混淆和容易出错。在统一初始化和上面的显式构造函数之间切换需要更改参数顺序,但编译器无法发现它。
答案 1 :(得分:3)
如果你想要一个函数来舍入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();
答案 2 :(得分:1)
讨论和思考:
我最初的想法是提供@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;
}