重载模板 Polynom 类的运算符[]
我正在编写一个模板 Polynom
类,其中 T
是其系数的数字类型。
多项式的系数存储在 std::vectorcoefficients[i]
对应于实数多项式中的x^i
。 (因此 x 的幂按递增顺序排列)。
保证coefficients
向量始终包含至少一个元素。 - 对于零多项式,它是T()
。
我想重载operator[]
来执行以下操作:
- 传递给operator[]的索引对应于我们要修改/读取其系数的X的幂。
- 如果用户只想读取系数,则应该抛出负索引,对于存储范围内的索引返回
coefficients.at(i)
- 并且合理 对于所有其他索引返回 0,而不是抛出。 - 如果用户想要修改系数,则应该抛出负索引,但让用户自由修改所有其他索引,即使指定的索引大于或等于coefficients.size( )。所以我们想以某种方式调整向量的大小。
我遇到的主要问题如下:
1.
如何区分读情况和写情况?一个人没有给我任何解释,但说写两个版本
const T& operator[] (int index) const;
T& operator[] (int index);
是不够的。但是,我认为编译器在读取情况下更喜欢 const 版本,不是吗?
2.
我想确保系数向量中不存储任何尾随零。因此,我必须以某种方式提前知道,“在我返回系数的可变 T&
之前”,用户想要分配什么值。我知道 operator[]
不会收到第二个参数。
显然,如果这个值不为零(不是 T()),那么我必须调整向量的大小并将适当的系数设置为传递的值。
但我不能提前这样做(在从 operator[]
返回 T&
之前),因为如果要分配的值是 T(),那么,只要我调整大小我提前输入系数向量,它最终会有很多尾随“零”。
当然,我可以检查该类的每个其他函数中是否有尾随零,并在这种情况下将其删除。对我来说这似乎是一个非常奇怪的决定,我希望每个函数都在假设向量的末尾没有零的情况下开始工作,如果它的大小> 1.
您能否建议我尽可能具体地解决这个问题? 我听说过一些关于使用重载的 operator=
编写可隐式转换为 T&
的内部类,但我缺乏详细信息。
预先非常感谢您!
I am writing a template Polynom<T>
class where T
is the numeric type of its coefficients.
The coefficients of the polynom are stored in an std::vector<T> coefficients
, where coefficients[i]
corresponds to x^i
in a real polynom. (so the powers of x are in increasing order).
It is guaranteed that coefficients
vector always contains at least one element. - for a zero polynom it is T()
.
I want to overload the operator[]
to do the following:
- The index passed to the operator[] corresponds to the power of X whose coefficient we want to modify / read.
- If the user wants to just read the coefficient, it should throw for negative indices, return
coefficients.at(i)
for indices within the stored range - and reasonably return 0 for all other indices, not throw. - If the user wants to modify the coefficient, it should throw for negative indices, but let user modify all other indices freely, even if the index specified is bigger than or equal to
coefficients.size()
. So we want to somehow resize the vector.
The main problem I have collided with is as follows:
1.
How do I distinguish between the read case and the write case? One person left me without an explanation but said that writing two versions:
const T& operator[] (int index) const;
T& operator[] (int index);
was insufficient. However, I thought that the compiler would prefer the const version in the read case, won't it?
2.
I want to make sure that no trailing zeros are ever stored in the coefficients
vector. So I somehow have to know in advance, "before" I return a mutable T&
of my coefficient, what value user wants to assign. And I know that operator[]
doesn't receive a second argument.
Obviously, if this value is not zero (not T()), then I have to resize my vector and set the appropriate coefficient to the value passed.
But I cannot do it in advance (before returning a T&
from operator[]
), because if the value to be assigned is T(), then, provided I resize my coefficients vector in advance, it will eventually have lots of trailing "zeroes".
Of course I can check for trailing zeroes in every other function of the class and remove them in that case. Seems a very weird decision to me, and I want every function to start working in assumption that there are no zeroes at the end of the vector if its size > 1.
Could you please advise me as concrete solution as possible to this problem?
I heard something about writing an inner class implicitly convertible to T&
with overloaded operator=
, but I lack the details.
Thank you very much in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以尝试的一个选项(我尚未测试过):
并定义:
这样,当您为“引用”分配一个值时,它应该可以访问多项式中的所有所需数据,并采取适当的操作。
我对您的实现不够熟悉,因此我将给出一个非常简单的动态数组的示例,其工作原理如下:
int索引
读取;先前未写入的元素应读取为0
;0
。这是一个非常简单的示例,目前的形式效率不高,但它应该证明这一点。
最终,您可能希望重载
operator&
以允许*(&v[0] + 5) = 42;
等内容正常工作。对于此示例,您可以让operator&
给出一个my_pointer
,它定义operator+
对其index
进行算术运算字段并返回一个新的my_pointer
。最后,您可以重载operator*()
以返回到my_ref
。One option you could try (I haven't tested this):
and define:
This way when you assign a value to the "reference" it should have access to all the needed data in the polynomial, and take the appropriate actions.
I am not familiar enough with your implementation, so I'll instead give an example of a very simple dynamic array that works as follows:
int index
without concern; elements not previously written to should read off as0
;0
.It's a very simple example and not very efficient in its current form but it should prove the point.
Eventually you might want to overload
operator&
to allow things like*(&v[0] + 5) = 42;
to work properly. For this example, you could have thatoperator&
gives amy_pointer
which definesoperator+
to do arithmetic on itsindex
field and return a newmy_pointer
. Finally, you can overloadoperator*()
to go back to amy_ref
.解决这个问题的办法是代理类(下面是未经测试的代码):
显然上面的代码没有优化(尤其是赋值运算符显然有优化的空间)。
The solution to this is a proxy class (untested code follows):
Obviously the code above is not optimized (especially the assignment operator has clearly room for optimization).
您无法通过运算符重载来区分读取和写入。您能做的最好的事情就是区分
const
设置和非const
设置中的使用,这就是您的代码片段的作用。所以:这听起来像是你两个问题的答案,因此,是有单独的
set
和get
函数。You cannot distinguish between read and write with operator overloads. The best you can do is distinguish between usage in a
const
setting and a non-const
setting, which is what your code snippet does. So:It sounds like the answer to both your questions, therefore, is to have separate
set
andget
functions.我看到您的问题有两种解决方案:
不要将系数存储在
std::vector
中,而是将它们存储在std::map< /代码>。这样您将只存储非零系数。您可以创建自己的基于
std::map
的容器,该容器将消耗存储在其中的零。这样,您还可以为具有较大 n 的 x^n 形式的多项式节省一些存储空间。添加一个内部类来存储索引(幂)和系数值。您将从
operator[]
返回对此内部类实例的引用。内部类将覆盖operator=
。在重写的operator=
中,您将获取存储在内部类实例中的索引(幂)和系数,并将它们刷新到存储系数的std::vector
中。< /p>I see two solutions to your problem:
Instead of storing the coefficients in a
std::vector<T>
store them in astd::map<unsigned int, T>
. This way you will ever only store non-zero coefficients. You could create your ownstd::map
-based container that would consume zeros stored into it. This way you also save some storage for polynomials of the form x^n with large n.Add an inner class that will store an index (power) and coefficient value. You would return a reference to an instance of this inner class from
operator[]
. The inner class would overwriteoperator=
. In the overriddenoperator=
you would take the index (power) and coefficient stored in inner class instance and flush them to thestd::vector
where you store your coefficients.这是不可能的。我能想到的唯一方法是提供一个特殊的成员函数来添加新系数。
编译器通过查看
Polynom
的类型来决定const
和非const
版本,而不是通过检查执行的操作类型关于返回值。This is not possible. The only way I can think of is to provide a special member-function for adding new coefficients.
The compiler decides between the
const
and non-const
version by looking at the type ofPolynom
, and not by checking what kind of operation is performed on the return-value.