c++ 中的基本运算符重载语法

发布于 2025-01-02 13:40:06 字数 1111 浏览 0 评论 0原文

我很难形成一个我想问的问题,所以让我举个例子:

假设我们正在开发一个 3d 系统,在该系统中我们定义了一个向量类 Vec3。出于明显的原因,我们重载了一些算术运算符。其中我们重载 * 运算符,以便它将返回两个向量的点积。现在我们的代码应该如下所示:

class Vec3{
private:
    float x, y, z;
public:
    float operator*(const Vec3&) const; //dot product
.
.
.

现在假设我们希望能够通过使用 * 运算符来缩放向量,例如浮点数。这可以通过声明以下内容来完成:

    Vec3 operator*(const float) const;
    friend Vec3 operator*(const float, const Vec3&);

这会产生两个重载,并且我想知道是否有一种方法可以只用一个重载,即我们声明它而不是上面的两行:

    friend Vec3 operator*(const Vec3&, const Vec3&);

然后为 Vec3 向量添加默认值以处理浮点转换。

最后一个示例适用于:

    Vec3 someVec3 = 1.0 * otherVec3; //through friend Vec3 operator*(const float, const Vec3&)

但不适用于此:

    Vec3 someVec3 = otherVec3 * 1.0;

因为编译器不知道使用两者中的哪一个:

    friend Vec3 operator*(const float, const Vec3&); //the one we want to use
or
    float operator*(const Vec3&) const; //the one for the dot product

有什么建议吗?

谢谢你!

I’m having a hard time forming a question of what I’m trying to ask so let me give you an example:

Say we are working on a 3d system where we have defined a vector class, Vec3. We overload some arithmetic operators for obvious resons. Among these we overload the *operator so that it will return the dot product of two vectors. Now our code should look something like this:

class Vec3{
private:
    float x, y, z;
public:
    float operator*(const Vec3&) const; //dot product
.
.
.

Now say that we want to be able to scale our vector by using the *operator with something, say a float. This could be done by declaring the following:

    Vec3 operator*(const float) const;
    friend Vec3 operator*(const float, const Vec3&);

This yeilds two overloads and I’m wondering if there’s a way to do it with just one, i.e. say we declare this instead of the above two lines:

    friend Vec3 operator*(const Vec3&, const Vec3&);

and then add default values for the Vec3 ctor to handle the convertion from float.

This last example would work for:

    Vec3 someVec3 = 1.0 * otherVec3; //through friend Vec3 operator*(const float, const Vec3&)

however not for this:

    Vec3 someVec3 = otherVec3 * 1.0;

as the compiler wouldn’t know which of the two to use:

    friend Vec3 operator*(const float, const Vec3&); //the one we want to use
or
    float operator*(const Vec3&) const; //the one for the dot product

Any suggestions?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沒落の蓅哖 2025-01-09 13:40:06

在这种情况下,我最初建议不要重载运算符,因为您的用户如何知道 * 是否表示点积或叉积(两者都是合理的含义,具体取决于预期的客户端使用)。我实际上建议不支持 operator* 并使用 dotcrossscale 成员。这样您就不必担心多次过载,并且您的用户很清楚他们将获得什么。

但是,如果您确实想继续使用运算符,那么有两个重载也没有什么问题。创建一个虚拟 Vec3 来进行缩放不仅在语义上不正确,而且还会增加少量不必要的开销。

In this case I would initially advise against operator overloading, because how are your users to know if * represents dot or cross product (both are reasonable meanings depending on expected client use). I would actually suggest just not supporting operator* and do it with dot, cross and scale members. Then you don't have to worry about multiple overloads and it's clear to your users what they're getting.

However if you do want to go ahead with the operators, there's nothing wrong with having two overloads. Creating a dummy Vec3 to do scaling is not only semantically incorrect it's going to add a small amount of unneeded overhead.

梦幻之岛 2025-01-09 13:40:06

Boost.Operators 可以完成大部分样板文件为你工作。例如:

class Vec3 
  : boost::multipliable2<Vec3, float>
{
public:
   // ... 

   Vec3 operator*=(float);
   // Vec3 operator*(Vec3, const float&) and
   // Vec3 operator*(const float&, Vec3) auto-generated
   // by multipliable. 
};

Boost.Operators can do most of the boiler-plate work for you. E.g.:

class Vec3 
  : boost::multipliable2<Vec3, float>
{
public:
   // ... 

   Vec3 operator*=(float);
   // Vec3 operator*(Vec3, const float&) and
   // Vec3 operator*(const float&, Vec3) auto-generated
   // by multipliable. 
};
就像说晚安 2025-01-09 13:40:06

几个重载并没有什么问题,尤其是如果它们可以很容易地相互实现的话:

Vec3 operator*(const float scale, const Vec3& vec)
{ return vec * scale; }

很难得到比这更简单的了!

There is nothing wrong in a couple of overloads, especially not if they can easily be implemented in terms of each other:

Vec3 operator*(const float scale, const Vec3& vec)
{ return vec * scale; }

It is hard to get it simpler than that!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文