Problem on template definition

S

shuisheng

Dear All;

Would you please help me to look at the following case:

//! Rotation.
enum Rotation {
NON_CYCLIC,
CYCLIC
};
//! Rotation.
enum Direction {
LEFT,
RIGHT
};

//! This is a class template of TinyVector
template<class _T, size_t _n>
class TinyVector
{
public:
//! Rotate.
template<Direction _dir, Rotation _rot>
TinyVector& Rotate(size_t n);
}

//! Rotate.
template<class _T, size_t _n>
template<Direction _dir, Rotation _rot>
inline typename TinyVector<_T, _n>& TinyVector<_T, _n>::Rotate(size_t
n)
{
...
return *this;
}

//! Rotate<LEFT, NON_CYCLIC>.
template<class _T, size_t _n>
template<>
inline typename TinyVector<_T, _n>& TinyVector<_T, _n>::Rotate<LEFT,
NON_CYCLIC>(size_t n)
{
...
return *this;
} // <-- Error position

Error C2768: 'TinyVector<_T,_n>::Rotate' : illegal use of explicit
template arguments

I realy appreciate your guys' help. It make me to learn c++ much more
comforably.

Shuisheng
 
S

shuisheng

shuisheng said:
Dear All;

Would you please help me to look at the following case:

//! Rotation.
enum Rotation {
NON_CYCLIC,
CYCLIC
};
//! Rotation.
enum Direction {
LEFT,
RIGHT
};

//! This is a class template of TinyVector
template<class _T, size_t _n>
class TinyVector
{
public:
//! Rotate.
template<Direction _dir, Rotation _rot>
TinyVector& Rotate(size_t n);
}

//! Rotate.
template<class _T, size_t _n>
template<Direction _dir, Rotation _rot>
inline typename TinyVector<_T, _n>& TinyVector<_T, _n>::Rotate(size_t
n)
{
...
return *this;
}

//! Rotate<LEFT, NON_CYCLIC>.
template<class _T, size_t _n>
template<>

Reverse those two template declaration. It becomes okay. Quite
interesting.

template<>
 
A

amparikh

shuisheng said:
Dear All;

Would you please help me to look at the following case:

//! Rotation.
enum Rotation {
NON_CYCLIC,
CYCLIC
};
//! Rotation.
enum Direction {
LEFT,
RIGHT
};

//! This is a class template of TinyVector
template<class _T, size_t _n>
class TinyVector
{
public:
//! Rotate.
template<Direction _dir, Rotation _rot>
TinyVector& Rotate(size_t n);
}

//! Rotate.
template<class _T, size_t _n>
template<Direction _dir, Rotation _rot>
inline typename TinyVector<_T, _n>& TinyVector<_T, _n>::Rotate(size_t
n)
{
...
return *this;
}

//! Rotate<LEFT, NON_CYCLIC>.
template<class _T, size_t _n>
template<>
inline typename TinyVector<_T, _n>& TinyVector<_T, _n>::Rotate<LEFT,
NON_CYCLIC>(size_t n)
{
...
return *this;
} // <-- Error position

You cannot specialize a template member function without first
specializing the class template.
so you need to first specialize the class template for a specific type.
 
K

Kai-Uwe Bux

shuisheng said:
//! Rotation.
enum Rotation           {
NON_CYCLIC,
CYCLIC
};
//! Rotation.
enum Direction          {
LEFT,
RIGHT
};

//! This is a class template of TinyVector
template<class _T, size_t _n>
class TinyVector
{
public:
//! Rotate.
template<Direction _dir, Rotation _rot>
TinyVector& Rotate(size_t n);
}

missing ";":
};

that one already causes a lot of confusing error messages to go away.
//! Rotate.
template<class _T, size_t _n>
template<Direction _dir, Rotation _rot>
inline typename TinyVector<_T, _n>& TinyVector<_T, _n>::Rotate(size_t n)

ditch the "typename"
{
...
return *this;
}

//! Rotate<LEFT, NON_CYCLIC>.
template<class _T, size_t _n>
template<>
inline typename TinyVector<_T, _n>& TinyVector<_T, _n>::Rotate<LEFT,
NON_CYCLIC>(size_t n)
{
...
return *this;
}   // <-- Error position

Finally, this last one cannot fly at all: as of the current standard,
partial specializations of function templates do not exist in C++. You have
to turn that into a class template. The class could be stateless and just
provide a static function.


You could try something like:

#include <cstddef>

typedef int Direction;
typedef int Rotation;

//! This is a class template of TinyVector
template<class T, size_t N >
class TinyVector;

template < Direction dir, Rotation rot >
struct alg;

template<>
struct alg< 0, 0 > {

template<class T, size_t N >
static
TinyVector<T,N> & rotate ( TinyVector<T,N> & arg ) {
return ( arg );
}

}; // alg;


template<class T, size_t N >
class TinyVector {

public:

template<Direction dir, Rotation rot>
TinyVector& Rotate(size_t n) {
return ( alg<dir,rot>::rotate( *this ) );
}

};




Best

Kai-Uwe Bux
 
N

Nate Barney

shuisheng said:
template<class _T, size_t _n>

Identifiers which begin with an underscore are reserved for the
implementation. Use T and n instead. If you really want to use an
underscore, you can use T_ and n_ .

Nate
 
V

Victor Bazarov

Nate said:
Identifiers which begin with an underscore are reserved for the
implementation.

Only in the global scope. Of course those that begin with a '_'
and a capital letter (like "_T" here) are always reserved, no
matter what scope.
Use T and n instead. If you really want to use an
underscore, you can use T_ and n_ .

I think many who use the leading underscore think that with it
their code looks cool because it looks more like the "internal
stuff" or the "implementation detail", or some such. Or, maybe
they think it would help avoid naming conflict somewhere down
the road (which it actually doesn't).

V
 
N

Nate Barney

Victor said:
Only in the global scope. Of course those that begin with a '_'
and a capital letter (like "_T" here) are always reserved, no
matter what scope.

Interesting, I didn't know that. In any case, it's probably best to
eschew leading underscores entirely.

Nate
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,002
Messages
2,570,261
Members
46,859
Latest member
VallieMcKe

Latest Threads

Top