I'm trying to create a class of fixed size vectors, to use mostly for geometrical purposes, where vector length doesn't change:
template<typename T, int n>
class FixedVector
{
private:
T m_rV[n]; // this is the only data member
public:
// class function members
...
}
This would have the advantage of compiler checking for operations with vectors of incompatible size.
I'm having problems when trying to build an operator* for this class (note: it is not a member). This operator should multiply the vector by a scalar, like this 3*[1,2,3]=[3,6,9].
template<typename T, int n>
FixedVector<T,n> operator*(const T &rX, const FixedVector<T,n> &cV) const
{ typename std::pointer_to_binary_function<T,T,T> op=(util::times<T>);
FixedVector<T,n> cT(cV, std::bind1st(op, rX));
return cT;
}
where times is the multiplication function of a scalar member of the vector
template<typename T>
inline T times(const T &t1, const T &t2)
{ return t1*t2;
}
the code for the constructor in line 4 is
template<typename T, int n>
FixedVector<T,n>::FixedVector(const T rV[n], T (*f)(const T &))
{ util::copy(m_rV, rV, n, f);
}
and pointer_to_binary_function and bind1st are STL functions from the header (Those who can help should know this already).
I'm getting the following compiler error in Visual Studio 2005 when calling
util::FixedVector<int,4> x; 3*x;
:
fixed_vector.hpp(212) : error 2440:
'initializing' : cannot convert from 'T (__cdecl *)(const T &,const T &)'
to 'std::pointer_to_binary_function<_Arg1,_Arg2,_Result>'
with
[
_Arg1=int,
_Arg2=int,
_Result=int
]
No constructor could take the source type, or constructor overload resolution was ambiguous
testproject.cpp(18) : see reference to function template instantiation 'util::FixedVector<T,n> util::operator *<T,4>(const T &,const util::FixedVector<T,n> &)' being compiled
with
[
T=int,
n=4
]
It appears that typename std::pointer_to_binary_function is correctly instantiated to std::pointer_to_binary_function However, times still remains to its basic signature: 'T (__cdecl *)(const T &,const T &)
--- AFTER SOME EDITING ----------------------------------------------------------------
It was indicated to me that a function that my constructor requests a plain function as parameter: T (*)(const T &t1, const T &t2) and that STL functional objects won't be accepted. The link here STL for_each served as a guide on how to do the corrections.
I started to changing from the util::copy function, called by constructor.
From: template void copy(T *dst, const T *src, size_t n, T (*f)(const T &)) { for (; n>0; n--, dst++, src++) { *dst = f(*src); } }
it became
template<typename T, typename Function>
void copy(T *dst, const T *src, size_t n, Function f)
{ for (; n>0; n--, dst++, src++)
{ *dst = (*f)(*src);
} }
Then, the constructor itself was templated. From:
template<typename T, int n>
FixedVector<T,n>::FixedVector(const T rV[n], T (*f)(const T &))
{ util::copy(m_rV, rV, n, f);
}
it is now
template<typename T, int n>
template<class Function>
FixedVector<T,n>::FixedVector(const FixedVector<T,n> &cV, Function f)
{ util::copy(m_rV, cV.m_rV, n, f);
}
Also added some consts to template instantiation parameters:
template<typename T, int n>
FixedVector<T,n> operator*(const T &rX, const FixedVector<T,n> &cV)
{ typename std::pointer_to_binary_function<const T,const T,T> op(times<T>);
FixedVector<T,n> cT(cV, std::bind1st(op, rX));
return cT;
}
But I still get the same error (only that T has been replaced by const T; note that adding a & to indicate reference (const T&) will trigger an error and it seems that templates have problems with this, Boost and TR1 creating special solutions to deal with this - see Wikipedia TR1 reference wrapper).
The exact line of the error is this:
typename std::pointer_to_binary_function<const T,const T,T> op(times<T>);
So I don't even reach the constructor.
I'd be very grateful with some extra ideas.
std::array<T, N>
? You can make the dot product into a non-member function. – Kerrek SBFixedVector<T,n> cT(cV, std::bind1st(op, rX));
supposed to do? Did you implement such a constructor? – Kerrek SBbind1st
is convertible to a function pointer; why don't you make the constructor argument aunary_function
? – Kerrek SB