Topic: template bug or syntax error?
Author: Terence Kelling <kelling@arlut.utexas.edu>
Date: 1998/05/20 Raw View
I am having the worst time trying to compile a template class in MS
Visual C++ ver 5.0 service pack 3 that defines member functions outside
of the class definition body. The following works fine if I define the
functions inside of the class, but when I define them outside, I get the
following error. To make matters more complicated, this will work fine
if I only declare either the non-const or const version and define it
outside of the class body.
Is this a bug or am I doing something wrong?
Thanks,
Terence
main.obj : error LNK2001: unresolved external symbol
"public: int * __thiscall container<int,class
std::allocator<int>>::begin(void)"
(?begin@?$container@HV?$allocator@H@std@@@@QAEPAHXZ)
#include <climits>
#include <memory>
#include <stdexcept>
#include <xutility>
using namespace std;
template<class T, class A = allocator<T> >
class container {
public:
// typedefs
typedef container<T, A> _Myt;
typedef A::pointer _Tptr;
typedef A::const_pointer _Ctptr;
typedef _Tptr iterator;
typedef _Ctptr const_iterator;
// constructors
explicit container(const A& Al = A()) : allocator_m(Al), base_m(0)
{
base_m = allocator_m.allocate(10, (void *)0);
}
// destructor
~container() {
allocator_m.deallocate(base_m, 10);
}
// get/set methods
iterator begin(void);// { return base_m; }
const_iterator begin(void) const;// { return ((const_iterator)
base_m); }
private:
A allocator_m;
iterator base_m;
};
template<class T, class A> inline
container<T, A>::iterator container<T, A>::begin(void) {
return base_m;
}
template<class T, class A> inline
container<T, A>::const_iterator container<T, A>::begin(void) const {
return ((const_iterator) base_m);
}
int main(void) {
container<int> c;
container<int>::iterator begin = c.begin();
return 0;
};
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Terence Kelling <kelling@arlut.utexas.edu>
Date: 1998/05/20 Raw View
I have narrowed the problem down to a problem with typedefs. MSVC seems
to have a problem with multiple typedefs. If I compile the code with
the typedefs given as comments, everything works fine, but if I compile
it as below, I get the linker error. Furthermore, if I put class foo
in a header file of it's own and include that file from main, I get
fatal error C1001: INTERNAL COMPILER ERROR.
Just to verify, am I missing a subtlety of C++ or is this a compiler bug?
Thanks,
Terence Kelling
#include <memory>
using namespace std;
template <class T, class A = allocator<T> >
class foo {
public:
typedef A::pointer iterator; // typedef T* iterator;
typedef A::const_pointer const_iterator; // typedef const T*
// const_iterator;
iterator begin(void);
const_iterator begin(void) const;
private:
A allocator_m;
iterator base_m;
};
template <class T, class A> inline
foo<T, A>::iterator foo<T, A>::begin(void) {
return base_m;
}
template <class T, class A> inline
foo<T, A>::const_iterator foo<T, A>::begin(void) const {
return base_m;
}
// #include "foo.h" // fatal error if you put the above in a header
// file and try to include it
int main(void) {
foo<int> f;
int* ptr = f.begin();
return 0;
};
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/05/21 Raw View
Terence Kelling <kelling@arlut.utexas.edu> writes:
> Just to verify, am I missing a subtlety of C++ or is this a compiler bug?
It may be a completely unrelated problem, but you're definitely
missing the `typename' keyword, that is mandatory before
template-argument dependent type names.
> typedef A::pointer iterator; // typedef T* iterator;
> typedef A::const_pointer const_iterator; // typedef const T*
> // const_iterator;
Make this:
typedef typename A::pointer iterator;
typedef typename A::const_pointer const_iterator;
And it may work.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]