Reputation: 46
I'm somehow new to templates and I'm trying to modify some library that provide matrix and vector operation to c++, i have a vector class which I'm trying to overload the operator() for it to handle an operation like this Vector(2:5) will return a vector that has elements 2,3,4,5 of the original vector, and I'm using a class called colon where colon(2:5) will represent the (2:5) effect as i found that c++ has no operator: . hope i gave a proper introduction. The relevant code is as follows
The Vector Class
template< size_t M, typename T = float >
class Vector
{
public:
typedef T value_type;
Vector operator-( const Vector& other ) const;
template <size_t N, typename T> Vector<N,T> operator()(const colon &cex) const;
.
.
}
and the corresponding implementation
template< size_t M, typename T >
template< size_t N,T>
Vector<N,T>
Vector<M,T>::operator()( const colon &cex ) const
{
long i, ii, st = 0, in = 0, en = 0, s;
cex.apply(M, st, in, en, s);
if (s && (st>0) && (st>M))
{
Vector<N,T> result;
for (i=st,ii=0;i+=in,ii++;i<=en,ii<N)
{
result(ii)=array(i);
return result;
}
}
return 0;
}
the return 0 here is just a place holder, it should return an empty vector. the colon class (which is taken from another library and modified by me).
class colon
{
public:
/// Colon expression '(:)'
colon() { _flag = 'a'; }
/// Colon expression of type '(2:5)'
colon(long s, long e) { _s = s; _i = 1; _e = e; _flag = 'r'; }
void apply(long s, long &f, long &i, long &l, long &n) const;
private:
/// Type of colon expression.
char _flag;
/// First index.
long _s;
/// Increment.
long _i;
/// Last index.
long _e;
}; /* class colon */
and the relevant implementation is
void
colon::apply(long n, long &st, long &in, long &en,
long &le) const
{
switch (_flag)
{
case 'r':
if ((_i == 0 ) || ((_e - _s) / _i < 0 )) le = 0;
else
{
st = _s;
in = _i;
en = _e - (_e - _s) % _i;
le = (_e - _s) / _i + 1;
}
break;
case 'a':
if (n)
{
st = 1;
in = 1;
en = n;
le = n;
}
else le = 0;
break;
}
}
when compiling this code i always receive the error
Error 1 error C2244: 'Vector::operator ()' : unable to match function definition to an existing declaration
and the output of the compiler is
error C2244: 'Vector<M,T>::operator ()' : unable to match function
definition to an existing declaration
definition
'Vector<N,T> Vector<M,T>::operator ()(const colon &) const'
existing declarations
'Vector<N,T> Vector<M,T>::operator ()(const colon &) const'
So What I'm doing wrong here?
Upvotes: 1
Views: 332
Reputation: 9089
First problem is that you write template function arguments wrong: template<size_t N,T>
. It shall be template<size_t N, typename T>
, otherwise it will be considered as non-type template parameter (some specific value of T
).
Second problem is that function template parameter name T
is ambiguos. Compiler could not know which T
it shall use, from class template parameter or from function one? Remember, function and class template parameters are unrelated. So you need to rename it:
template<size_t M, typename T> class Vector
{
public:
template <size_t N, typename X> Vector<N,X> operator()() const;
};
template<size_t M, typename T>
template<size_t N, typename X> Vector<N,X> Vector<M,T>::operator()() const
{
}
But actually if you don't need cross-type operations and X
will be always the same type as T
you could just skip it in function and parametrize it only by size:
template<size_t M, typename T> class Vector
{
public:
template <size_t N> Vector<N,T> operator()() const;
};
template<size_t M, typename T>
template<size_t N> Vector<N,T> Vector<M,T>::operator()() const
{
}
Upvotes: 1
Reputation: 9547
In your declaration you write:
template< size_t M, typename T = float >
class Vector
{
template <size_t N, typename T>
Vector<N,T> operator()(const colon &cex) const
and in your definition you write:
template< size_t M, typename T >
template< size_t N,T>
Vector<N,T>
Vector<M,T>::operator()( const colon &cex ) const
Notice the difference in the second template line:
template <size_t N, typename T>
vs.
template< size_t N,T>
You are missing the typename
there. So instead of passing a type to T you expect to get passed an instance of T
(which is only possible if T
is an integral type).
This shows that your declaration and definition do in fact differ and where the error originates from.
As your second T
would hide the first (which is not allowed - see comments), I think you either want to rename the second T
and add the typename
in the definition or you want to remove the second T
altogether.
Upvotes: 1