【问题标题】:Create a literal operator function that takes 2 input parameters创建一个接受 2 个输入参数的文字运算符函数
【发布时间】:2019-01-30 15:09:51
【问题描述】:

我有一个定义的类型Coordinates,如下所示:

#include <array>
using Coordinates = std::array<double, 3>;

为此,我称之为以下运算符重载函数:

Coordinates operator+(const Coordinates& lhs, const Coordinates& rhs);
Coordinates operator*(const Coordinates& lhs, const Coordinates& rhs);

两个重载都有效,所以如果我有 2 个 Coordinates 变量:

C1 = { 1., 2., 3.}C2 = { 1., 2., 3. }

C1+C2 返回{ 2., 4., 6.}

C1*C2 返回{ 1., 4., 9.}

现在我想定义一个*+ 运算符,这样:

C1*+C2 返回1. + 4. + 9.14.

我尝试了以下实现:

Coordinates operator*+(const Coordinates& lhs, const Coordinates& rhs)
{
    return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
}

但是,*+ 不是预定义的运算符。然后我尝试了这种格式:

Coordinates operator "" *+(const Coordinates& lhs, const Coordinates& rhs)
{
    return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
}

但我明白了:invalid literal operator name。这是可以理解的:

double operator "" _d_(const Coordinates& lhs, const Coordinates& rhs)
{
    return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
} 

_d_ 代表点积中的点,但现在我收到此错误too many parameters for this literal。是否可以为点积定义一个运算符,还是我必须编写一个dot() 函数?

【问题讨论】:

  • 用户定义的文字是一种创建新文字类型的方式。就像无法组成自己的运算符一样,您也不能拥有具有两个值的文字。
  • 我会避免只为外国类重载运算符。未来的 std 可能会合法地为数组添加 operator +,从而导致 ODR 可能中断。
  • 不确定 - 您需要 current operator* 来做什么,换句话说:哪个数学会使用组件式产品?让operator* 计算点积(您的新操作员会做什么)并只删除按组件计算的点积不是更有意义吗?
  • 文字运算符用于完全不同的事情......
  • @Aconcagua 我需要它来进行缩放,我这样做是为了有限元目的,这涉及到大量的局部到全局映射,反之亦然。我可以定义Scaling = Coordinates { a, b, c} 并通过缩放*顶点来缩放我的所有顶点,因为我的顶点也是Coordinates。至于文字运算符我不知道,直到我大约 20 分钟前阅读。我正在尝试探索我的选择。我试图通过重载++ 来解决它,以对所有内部值求和,但这只返回 int 并且我无法更改它。如果可行,我可以做类似(C1*C2)++

标签: c++ operators


【解决方案1】:

您只能为您的类型重载 38 个现有运算符。列在这里:https://en.cppreference.com/w/cpp/language/operators

op - 以下任何 38 个 (C++20 前) 39 个 (C++20 起) 运营商:点击+ 987654324 * 987654326 % 987654328 &amp; 987654330 ~ 987654332 = 987654334 &gt; 987654336 -= *= 987654339 %= 987654341 &amp;= 987654343 &lt;&lt; 987654345 &gt;&gt;= 987654347 == 987654349 &lt;= 987654351 &lt;=&gt; (因为C++20)&amp;&amp;||++--,-&gt;*-&gt;-&gt;()[@987654

文字运算符处理单个参数并将文字(如 42,“foobar”)转换为对象。由于您已经拥有对象,因此您必须使用运算符重载。选择任何可用的。

【讨论】:

  • 我明白了,谢谢。我只是因为缺乏经验而问,希望有人能给我一个明确的答案。
【解决方案2】:

首先,您可以查看list of operators 以查看此处存在的内容,了解哪些可以重载,哪些不能重载。

关于第二点,您可能可以尝试使用this answer 之类的方法来制作自定义运算符。请记住,这在技术上并不是一个新的运算符(因为您无法在 C++ 中创建自己的运算符),但确实涉及一些模板魔术来完成相同的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-05
    • 2021-02-16
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-20
    相关资源
    最近更新 更多