[GiNaC-devel] [PATCH] Fix compilation failure due to (template) operator- defined in factor.cpp
Alexei Sheplyakov
varg at metalica.kh.ua
Mon Feb 23 13:03:16 CET 2009
GiNaC 1.5.0 fails to compile with g++ 3.4:
/bin/bash ../libtool --tag=CXX --mode=compile ccache g++-3.4 -DHAVE_CONFIG_H -I. -I../../../../work/sw/GiNaC/ginac -I../config -I/home/pc7135/varg/target/x86_64-linux-gnu/include -Wall -O2 -g -pipe -funroll-loops -ffast-math -finline-limit=1200 -m64 -march=k8 -mfpmath=sse -msse2 -MT factor.lo -MD -MP -MF .deps/factor.Tpo -c -o factor.lo ../../../../work/sw/GiNaC/ginac/factor.cpp
libtool: compile: ccache g++-3.4 -DHAVE_CONFIG_H -I. -I../../../../work/sw/GiNaC/ginac -I../config -I/home/pc7135/varg/target/x86_64-linux-gnu/include -Wall -O2 -g -pipe -funroll-loops -ffast-math -finline-limit=1200 -m64 -march=k8 -mfpmath=sse -msse2 -MT factor.lo -MD -MP -MF .deps/factor.Tpo -c ../../../../work/sw/GiNaC/ginac/factor.cpp -fPIC -DPIC -o .libs/factor.o
../../../../work/sw/GiNaC/ginac/factor.cpp: In function `unsigned int GiNaC::unnamed::next_prime(unsigned int)':
../../../../work/sw/GiNaC/ginac/factor.cpp:1330: warning: converting of negative value `-0x00000000000000001' to `size_t'
stl_vector.h: In member function `size_t vector<GiNaC::unnamed::EvalPoint>::size() const':
stl_vector.h:375: error: ambiguous overload for 'operator-' in '((const vector<GiNaC::unnamed::GiNaC::unnamed::EvalPoint> *)this)->vector<GiNaC::unnamed::GiNaC::unnamed::EvalPoint>::end() - ((const vector<GiNaC::unnamed::EvalPoint> *)this)->vector<GiNaC::unnamed::EvalPoint>::begin()'
stl_iterator.h:759: note: candidates are: typename const_iter::difference_type operator-(const const_iter &, const const_iter &)
../../../../work/sw/GiNaC/ginac/factor.cpp:254: note: const_iter GiNaC::unnamed::operator-(const const_iter &, const const_iter &)
stl_deque.h:825: error: ambiguous overload for 'operator-' in '((const _Deque_base<GiNaC::unnamed::ModFactors> *)((const deque<GiNaC::unnamed::ModFactors> *)this))->_Deque_base<GiNaC::unnamed::ModFactors>::_M_impl._Deque_base<GiNaC::unnamed::ModFactors>::_Deque_impl::_M_finish - ((const _Deque_base<GiNaC::unnamed::ModFactors> *)((const deque<GiNaC::unnamed::ModFactors> *)this))->_Deque_base<GiNaC::unnamed::ModFactors>::_M_impl._Deque_base<GiNaC::unnamed::ModFactors>::_Deque_impl::_M_start'
stl_deque.h: In member function `size_t deque<GiNaC::unnamed::ModFactors>::size() const':
../../../../work/sw/GiNaC/ginac/factor.cpp:1534: instantiated from here
stl_deque.h:671: instantiated from `deque<GiNaC::unnamed::ModFactors>::deque(const deque<GiNaC::unnamed::ModFactors> &)'
../../../../work/sw/GiNaC/ginac/factor.cpp:1534: instantiated from here
../../../../work/sw/GiNaC/ginac/factor.cpp:254: note: iter GiNaC::unnamed::operator-(const iter &, const iter &)
../../../../work/sw/GiNaC/ginac/container.h:375: error: ambiguous overload for 'operator-' in 'last - first'
../../../../work/sw/GiNaC/ginac/container.h: In member function `void GiNaC::container< <template-parameter-1-1> >::read_archive(const GiNaC::archive_node &, GiNaC::lst &)':
../../../../work/sw/GiNaC/ginac/factor.cpp:2586: instantiated from here
../../../../work/sw/GiNaC/ginac/factor.cpp:2586: instantiated from here
stl_iterator.h:759: note: typename const_iter::difference_type operator-(const const_iter &, const const_iter &)
../../../../work/sw/GiNaC/ginac/container.h:375: error: ambiguous overload for 'operator-' in 'last - first'
../../../../work/sw/GiNaC/ginac/container.h: In member function `void GiNaC::container< <template-parameter-1-1> >::read_archive(const GiNaC::archive_node &, GiNaC::lst &)':
../../../../work/sw/GiNaC/ginac/factor.cpp:2586: instantiated from here
../../../../work/sw/GiNaC/ginac/factor.cpp:2586: instantiated from here
stl_iterator.h:759: note: typename const_iter::difference_type operator-(const const_iter &, const const_iter &)
The following (silly) code makes the problem easier to analyze:
namespace N1
{
template<typename T1, typename T2> struct A
{
T1 val;
typedef T2 diff_t;
explicit A(const T1& t) : val(t) { }
};
template<typename T>
typename T::diff_t operator-(const T& x, const T& y)
{
typedef typename T::diff_t diff_t;
return diff_t(x.val - y.val);
}
} // namespace N1
namespace N2
{
template<typename T> T operator-(const T& x, const T& y)
{
return T(x.val - y.val);
}
int f()
{
::N1::A<int, long> a(1), b(1);
return (a - b).val;
// ill-formed: both
// N1::A N2::operator-(const N1::A&, const N1::A&)
// and
// N1::A::diff_t N1::operator-(const N1::A&, const N1::A&)
// match.
}
} // namespace N2
The fix is simple: declare (and define) operator- (and operator+) only
for (univariate) polynomials.
---
ginac/factor.cpp | 32 ++++++++++++++++++++++++++++++--
1 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/ginac/factor.cpp b/ginac/factor.cpp
index b8a1fb8..2f9157b 100644
--- a/ginac/factor.cpp
+++ b/ginac/factor.cpp
@@ -218,8 +218,32 @@ static void expt_pos(umodpoly& a, unsigned int q)
}
}
+template<bool COND, typename T = void> struct enable_if
+{
+ typedef T type;
+};
+
+template<typename T> struct enable_if<false, T> { /* empty */ };
+
+template<typename T> struct uvar_poly_p
+{
+ static const bool value = false;
+};
+
+template<> struct uvar_poly_p<upoly>
+{
+ static const bool value = true;
+};
+
+template<> struct uvar_poly_p<umodpoly>
+{
+ static const bool value = true;
+};
+
template<typename T>
-static T operator+(const T& a, const T& b)
+// Don't define this for anything but univariate polynomials.
+static typename enable_if<uvar_poly_p<T>::value, T>::type
+operator+(const T& a, const T& b)
{
int sa = a.size();
int sb = b.size();
@@ -250,7 +274,11 @@ static T operator+(const T& a, const T& b)
}
template<typename T>
-static T operator-(const T& a, const T& b)
+// Don't define this for anything but univariate polynomials. Otherwise
+// overload resolution might fail (this actually happens when compiling
+// GiNaC with g++ 3.4).
+static typename enable_if<uvar_poly_p<T>::value, T>::type
+operator-(const T& a, const T& b)
{
int sa = a.size();
int sb = b.size();
--
1.5.6.5
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 835 bytes
Desc: Digital signature
URL: <http://www.ginac.de/pipermail/ginac-devel/attachments/20090223/81df6151/attachment.sig>
More information about the GiNaC-devel
mailing list