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;
inline T& operator()( size_t index );
inline const T& operator()( size_t index ) const;
template <size_t N> Vector<N,T> operator()(const colon &cex) const;
.
.
}
and the corresponding implementation
template< size_t M, typename T >
template< size_t N>
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;
}
}
The code used to test the functionality is
bool ok = true;
Vector< 4, double > v;
double data[] = { 1, 2, 3, 4 };
v.iter_set( data, data+4 );//just puts elements of data inside v with the same type
// test Vector colon
{
bool ok = true;
Vector<3,long> test;
test=v(colon(2,4));//Problem
}
The error now is
C2664: 'const double &Vector<M,T>::operator ()(size_t) const' :
cannot convert parameter 1 from 'colon' to 'size_t'
output of compiler is
error C2664: 'const double &Vector<M,T>::operator ()(size_t) const' :
cannot convert parameter 1 from 'colon' to 'size_t'
with
[
M=4,
T=double
]
No user-defined-conversion operator available that can perform this conversion,
or the operator cannot be called
???? help is appreciated
I have too much to say to fit it into a comment, so I will use the answer for this (although it does not answer your question directly):
You need to know what your use cases will be.
If you are going to do much with runtime variables, then there is no sense in implementing it all in templates. If you want to use templates only, then you need to do so too with
class colon. I will give you some hints to both.First let me explain your problem in more detail than what the comments could say.
Lets see few use cases assuming we have a
Vector<5, int> vec;.Case “compile-time size”:
For this code everything is known at compile time so it would be possible to do this at compile time (though it is unnecessary ugly for this purpose).
Case “run-time size”:
See those
aandbvariables? Do you know what values they hold, when you write the program? No you cannot because the user should input them. They could be0:0or0:4or42:1337, who knows what the user will enter (accidentally). When you do not know the value ofaandbyou also do not know what will stand at?, but you will have to know at compile-time, because every template argument has to be known at compile-time.Now you need to know what you want to do. Do you want to work with
a:b(run-time parameters) or do you only ever want to enter constants like1:3(compile-time parameters). Depending on this you need to choose, how to implementVector<n,T>::operator().You see: As soon as the size of the
Vectordepends on run-time values it cannot be determined at compile-time and it is therefore not possible to return the right sized vector.You could however implement a compile-time-sized and a run-time-sized vector and colon class to enable both at the cost of a more complex implementation. They would give following pattern:
This pattern would be necessary for any operation to interoperate between the run-time and compile-time types of Vector and colon.