|
-
May 14th, 2006, 11:34 PM
#1
Template function not generated?
I'm trying to make a simple vector class using meta programming. I'm using GCC's 3.3.4 compiler. Here's the code.
Code:
template<int N, int I = 0, int Stride = 1>
class VecOps
{
enum { loopflag = (I < N-1) ? 1 : 0 };
public:
template<class expr>
static inline void Zero(typename expr::iterator v) {
v[I] = typename expr::value_type();
VecOps<loopflag*N, loopflag*(I+1)>::Zero(v);
}
};
template<>
class VecOps<0>
{
public:
template<class expr>
static inline void Zero(typename expr::iterator v) {
}
};
template<class T, std::size_t dims>
class Vector
{
public: //exactly the same a boosts array class definitions
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
private:
value_type v[dims];
public:
Vector() {
VecOps<dims>::Zero(begin()); //error references this
}
iterator begin() {
return &v[0];
}
iterator end() {
return &v[dims-1];
}
};
When compiling, I get the following error:
error: no matching function for call to `VecOps<3, 0, 1>::Zero(int*)
What am I doing wrong? GCC compiled the blitz++ library perfectly.
-
May 14th, 2006, 11:52 PM
#2
Re: Template function not generated?
Please include all necessary header files.
Regards,
Paul McKenzie
-
May 14th, 2006, 11:56 PM
#3
Re: Template function not generated?
Also, please include the main() program that instantiates this type.
Regards,
Paul McKenzie
-
May 15th, 2006, 12:24 AM
#4
Re: Template function not generated?
OK, here's repost with all the modifications McKenzie asked for.
Code:
#include <cstdlib>
#include <iterator>
template<int N, int I = 0, int Stride = 1>
class VecOps
{
enum { loopflag = (I < N-1) ? 1 : 0 };
public:
template<class expr>
static inline void Zero(typename expr::iterator v) {
v[I] = typename expr::value_type();
VecOps<loopflag*N, loopflag*(I+1)>::Zero(v);
}
};
template<>
class VecOps<0>
{
public:
template<class expr>
static inline void Zero(typename expr::iterator v) {
}
};
template<class T, std::size_t dims>
class Vector
{
public: //exactly the same a boosts array class definitions
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
private:
value_type v[dims];
public:
Vector() {
VecOps<dims>::Zero(begin());
}
iterator begin() {
return &v[0];
}
iterator end() {
return &v[dims-1];
}
};
int main(int argc, char *argv[])
{
Vector<int, 3> v;
return EXIT_SUCCESS;
}
-
May 15th, 2006, 12:30 AM
#5
Re: Template function not generated?
This one compile but I am not sure if it meets your needs.
Code:
template<int N, int I = 0, int Stride = 1>
class VecOps
{
enum { loopflag = (I < N-1) ? 1 : 0 };
public:
template<class expr>
static inline void Zero(typename expr &v) {
v.begin()[I] = typename expr::value_type();
VecOps<loopflag*N, loopflag*(I+1)>::Zero(v);
}
};
template<>
class VecOps<0>
{
public:
template<class expr>
static inline void Zero(typename expr &v) {
}
};
template<class T, std::size_t dims>
class Vector
{
public: //exactly the same a boosts array class definitions
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
private:
value_type v[dims];
public:
Vector() {
VecOps<dims>::Zero(*this); //error references this
}
iterator begin() {
return &v[0];
}
iterator end() {
return &v[dims-1];
}
};
int main()
{
Vector<int, 10> v;
}
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
May 15th, 2006, 12:38 AM
#6
Re: Template function not generated?
Dope, dumb mistake. I know exactly what is happening now. The template is actually generating the function for Vector::iterator. It then looks to find Vector::iterator::iterator. It gets confused and says there is no matching function call. Here's the declaration the compiler sees.
void VecOps<3, 0, 1>::Zero( int*::iterator v)
You would think that this would set off all sort of errors, but I guess not.
Thanks for the help.
-
May 15th, 2006, 01:52 AM
#7
Re: Template function not generated?
In fact, both of these lines in your original code fail to compile.
Code:
static inline void Zero(typename expr::iterator v) {
v[I] = typename expr::value_type();
//...
The second line requires value_type to be available by expr. Thus, by passing *this into VecOps<...>::Zero(), I am making Vector<...>::value_type available in VecOps<...>::Zero()
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
May 15th, 2006, 02:14 AM
#8
Re: Template function not generated?
I suppose there is only one solution then. That is to add another template argument (maybe a couple because of other things I will be using the class for). Here's what I came up with (I'm not sure if my modification a good).
Code:
template<int N, typename expr1, typename expr2 = expr1, int I = 0, int Stride = 1>
class VecOps
{
enum { loopflag = (I < N-1) ? 1 : 0 };
typedef typename expr1::iterator iterator;
typedef typename expr1::const_iterator const_iterator;
typedef typename expr1::value_type value_type;
typedef VecOps<loopflag*N, expr1, expr2, loopflag*(I+N)> Next;
public:
static inline void Zero(iterator v) {
v[I] = value_type();
Next::Zero(v);
}
};
template<typename expr1>
class VecOps<0, expr1>
{
typedef typename expr1::iterator iterator;
typedef typename expr1::const_iterator const_iterator;
typedef typename expr1::value_type value_type;
public:
static inline void Zero(iterator v) {
}
};
template<class T, std::size_t dims>
class Vector
{
public: //exactly the same a boosts array class definitions
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
private:
value_type v[dims];
typedef VecOps<dims, Vector> Ops;
public:
Vector() {
Ops::Zero(begin());
}
iterator begin() {
return &v[0];
}
iterator end() {
return &v[dims-1];
}
};
int main(int argc, char *argv[])
{
Vector<int, 3> v;
return EXIT_SUCCESS;
}
I also discovered that instantiating a template like this does not seems to be possible.
VecOps<3>::Zero<Vector>(...);
Is there any reason why this is illegal?
-
May 15th, 2006, 05:16 AM
#9
Re: Template function not generated?
 Originally Posted by binarybob0001
I also discovered that instantiating a template like this does not seems to be possible.
VecOps<3>::Zero<Vector>(...);
Is there any reason why this is illegal?
Sorry, I have not idea if the code is legal. Probably you like to test it with Comeau compiler since it is one of the best compiler that conform to the standard.
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
May 15th, 2006, 07:00 AM
#10
Re: Template function not generated?
 Originally Posted by binarybob0001
I also discovered that instantiating a template like this does not seems to be possible.
VecOps<3>::Zero<Vector>(...);
Is there any reason why this is illegal?
It is invalid as it does not help instantiate neither the first VecOps template nor its specialization. When you say <3> - which template do you expect to get instantiated? First? - No - minimum requirement for that is an int and a type for expr1. Second? - No - minimum requirement for that is a type for expr1. In fact, I think this is wrong:
Code:
template<typename expr1>
class VecOps<0, expr1>
I think that specialization parameter (second line above) has to be a distinct type. Guys, correct me if I am wrong. Regards.
Last edited by exterminator; May 15th, 2006 at 07:14 AM.
Reason: missed 'n' / 'e'
Can you help me with my homework assignment?, Before you post!, Use code tags, How to post!, Codeguru technical FAQs, C++ FAQ Lite, Stroustrup: C++ Style and Technique FAQ, Guru of the Week, Comeau C and C++ FAQs, Comeau C++ Templates FAQs, CUJ @ DDJ, Spam threshold
My Blogs : Learning C++ is fun | Abnegator's reflections
Open Threads : C++ Aha! Moments | Nature of work in C++?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|