Couldn't break this into a smaller example... So I'm using an std::multimap
to store some values... It's a simple polynomial class.
The problem is the last function, which multiplies two polynomials. As it multiplies them, it produces a polynomial with multiple terms, which can be summed together (2x^2 + 3x^2 => 5x^2)
.
So I try to do that and Visual Studio complains (Debug Assertion Failed! Expression: map/set iterator not dereferencable)
. Tested and worked fine with Clang and GCC. Also, it works perfectly with Visual Studio in Release mode, so I thought this might be an error on my part or something with the logic! So my question is this: is the following code valid and correct? If not, how should I go about improving it? Don't comment too much on the other parts, please.
#include <iostream>
#include <cstddef>
#include <map>
#include <iterator>
#include <initializer_list>
//DIRTY YET SO BEAUTIFUL HACK //don't judge the macro :P
#define EXPAND_PACK(FUN) \
using type = int[]; \
type{ 0, ((FUN), void(), 0)... }
template<class T>
class polynomial
{
private:
struct _custom_compare //for std::multimap to sort properly
{
bool operator()(const std::size_t& a, const std::size_t& b) const
{
return a > b;
}
};
private:
std::multimap<std::size_t, T, _custom_compare> _data;
public:
template<class... Args>
polynomial(Args&&... pack)
{
std::size_t power = sizeof...(pack)-1;
EXPAND_PACK(_data.emplace(power--, pack));
}
auto operator*(const polynomial &rhs) const { return _multiply(rhs); }
friend std::ostream& operator<<(std::ostream& os, const polynomial& poly)
{
//implementation of this not important
}
private:
auto _multiply(polynomial rhs) const
{
polynomial lhs(*this);
polynomial<decltype((*_data.cbegin()).second + (*rhs._data.cbegin()).second)> ret;
for (const auto& i : lhs._data)
{
for (const auto& j : rhs._data)
ret._data.emplace(i.first + j.first, i.second * j.second);
}
decltype(ret) new_ret;
std::size_t power = (*ret._data.cbegin()).first;
decltype((*ret._data.cbegin()).second + (*ret._data.begin()).second) sum = 0;
//POINT OF INTEREST HERE!!
for (auto i = ret._data.cbegin(); i != ret._data.cend(); )
{
while ((*i).first == power)
{
sum += (*i).second;
++i;
}
new_ret._data.emplace(power, sum);
sum = 0;
--power;
}
return new_ret;
}
};
int main()
{
polynomial<int> p(3, 4);
polynomial<int> p2(5, 8, 4);
std::cout << p * p2;
}
Aucun commentaire:
Enregistrer un commentaire