I'm receiving a compiler error
/Developer/boost/boost/numeric/ublas/expression_types.hpp:184:16: fatal error: recursive template instantiation exceeded maximum depth of 512
from clang++ or indefinite compiling with >10GB memory usage from g++ 4.2.1.
I'm trying to create a helper function that subtracts a scalar from each element of a vector. Thinking generically at first, I planned to have the specific vector storage type a template parameter. That being said, I'm realizing I don't know how to make the definition work for both ublas
and std
vectors at this point (without specialization). But I'm still wondering what is happening / the reason for my compile troubles?
The problem is readily demonstrated with the below code when complied with the boost library, e.g.
g++ -I/path/boost bug_demo.cpp
Is there a bug in boost or in my code?
// demo code does not compiler, instead error for recursive template instantiation
//---------------------------------------------------------
#include <boost/numeric/ublas/vector.hpp>
namespace ublas = boost::numeric::ublas; // boost ublas will be the implementation for basic vector container
typedef ublas::vector<double> DVEC; // double vector shorthand
// ********* problem function ***********
template <typename vec_t, typename scalar_t>
vec_t operator-( const vec_t & vec, scalar_t scalar )
{
ublas::scalar_vector<scalar_t> scalar_v(vec.size(), scalar);
return vec - scalar_v;
}
// this non-template version works fine.
/* DVEC operator-( const DVEC & vec, double scalar )
{
ublas::scalar_vector<double> scalar_v(vec.size(), scalar);
return vec - scalar_v;
}
*/
DVEC vectorFunc( const DVEC& x )
{
double bnew=0.0;
DVEC x_bnew;
x_bnew = operator-(x,bnew);
return x_bnew;
}
int main()
{
DVEC inputVector(2);
inputVector[0] = 1.0; inputVector[1] = 2.0;
DVEC output = vectorFunc( inputVector );
return 0;
}
Your operator - ()
function is setting up an infinite template instantiation recursion by invoking itself when doing vec - scalar_v
. Although the name of the parameter type is scalar_t
, this is just a name and it can match any type, including a scalar_vector<scalar_t>
.
Thus, the line xbnew = operator - (x, bnew)
will cause the instantiation of:
operator - <DVEC, double>()
The last line in that operator template will in turn cause the instantiation of:
operator - <DVEC, scalar_vector<double>>()
Then, the last line in the same operator template will cause the instantiation of:
operator - <DVEC, scalar_vector<scalar_vector<double>>>()
And so on until the compiler reaches the maximum instantiation recursion depth.