Simple question: Why cannot deduce template argument?
-
The cross product accepts matrix of N vectors, each has dimentionality N+1:
template<int N, class T> inline Vector<N+1,T> CrossProduct(Matrix<N, Vector<N+1,T> const> const &m) { ... }When I call it, I get "cannot deduce template argument for T" compiler error:
Vector<3,double> r = CrossProduct( Matrix<2,Vector<3,double> const>( ... ) );How to fix it? I do not like to write template parameters each time:
Vector<3,double> r = CrossProduct<2,double>( Matrix<2,Vector<3,double> const>( ... ) );Edit: surprisingly, it can work with overload:
template<class T> inline Vector<3,T> CrossProduct(Matrix<2, Vector<3,T> const> const &m) { ... } ... Vector<3,double> r = CrossProduct( Matrix<2,Vector<3,double> const>( ... ) ); //No error here
-
SAn schrieb:
The cross product accepts matrix of N vectors, each has dimentionality N+1:
template<int N, class T> inline Vector<N+1,T> CrossProduct(Matrix<N, Vector<N+1,T> const> const &m) { ... }When I call it, I get "cannot deduce template argument for T" compiler error:
Vector<3,double> r = CrossProduct( Matrix<2,Vector<3,double> const>( ... ) );That is not a context, in which N can be deduced (14.8.2.4/14) - in short, because a non-type template parameter cannot be deduced from an expression (here: N+1). One solution would be to use different non-type parameters and then filter using sfinae, if the conditions are no satisfied:
template<int M, int N, class T> inline typename enable_if_c<M==N+1,Vector<M,T> >::type CrossProduct(Matrix<N, Vector<M,T> const> const &m)
-
Thank you!
I have done this way:
template<int N, class V> inline typename enable_if_c<V::dim==N+1,V>::type CrossProduct(Matrix<N, V const> const &m)Where vector contain declaration to get it dimention:
template<int N, class T> class Vector {public: static int const dim = N; ... };camper, your knowledge is as you are one of the developers of the C++ standard
.
-
SAn schrieb:
camper, your knowledge is as you are one of the developers of the C++ standard
.not quite.
If you wonder why such contexts cannot be used to deduce a nontype template eargument, consider what it would mean to allow these cases. It would either require to specify the exact kinds of expressions that could be used or to require the implementor to include an equation solver in the compiler:template <int N> void foo(int (&)[N*N]); // N positive or negative ?is already not quite as simple as an addition.
Either solution would increase compiler complexity while the posible gain is doubtful. With functions one could almost always get away with enable_if. And if we wanted to partially specialise a class template some kind of indirection should be possible in general.