I we have big computation geometry library. There is a problem in it's kernel. We have definitions scalar taits, and helper accesors in form of free functions, to simply write cg::epsilon<T>()
instead of cg::scalar_traits<T>::epsilon
. But problem that under vs2008 and vs2010 it sometimes argues that it could not deduce template parameter for T
in cg::epsilon<T>
. On other compilers in LWS works fine.
Reduced version to reproduce:
namespace cg
{
template<class S>
S epsilon();
template<>
double epsilon<double>() {return 1;}
template<>
float epsilon<float>() {return 1;}
template<class S>
bool eq(S a, S b, S eps = cg::epsilon<S>())
{
return true;
}
}
int main(int argc, char* argv[])
{
cg::eq(0.0, 0.0);
cg::eq(0.0f, 0.0f);
return 0;
}
Are there some workarounds to make accessors work?
PS: We using cg::scalar_traits<S>::epsilon()
, that helps, where error occurs, but that too much verbose
Research: Even declarated as
template<class S>
bool eq(S a, S b, S eps = cg::epsilon<double>())
compiler complains that he could not deduce S for cg::epsilon.
My guess is that the compiler is using the defaulted parameter S eps = cg::epsilon<S>()
in the deduction of S
. For this, it needs to look at the declaration of cg::epsilon<S>()
but at this time it doesn't know S
yet.
A workaround is avoiding the default value for the third parameter and add two different overloads: the first takes three arguments (a
, b
and eps
) and the second takes only two (a
and b
). The latter gets eps
from cg::epsilon<S>()
(at this time S
has already been deduced) and delegates the call to the former as the below code shows:
template<class S>
bool eq(S a, S b, S eps)
{
return true;
}
template<class S>
bool eq(S a, S b)
{
S eps = cg::epsilon<S>();
return eq(a, b, eps);
}