error when using class template

I have a class template that is structured like the following:

"template <class T> class Vec"

and I am trying to create a Vec object like the following:

"Vec<char> data"

and I am receiving the BELOW ERRORS. Can someone pls help. Thx!!!


[COMPILER ERROR MSGS]
Compiling...
ch12_sec1_making_class_objs_act_like_values.cpp
c:\program files\microsoft visual studio 9.0\vc\include\iterator(22) : error C2039: 'reference' : is not a member of 'Vec'
with
[
T=char
]
c:\home_folder\laptop_after_rebuild\c++ practice codes\accelerated_chapter_0\accelerated_chapter_0\ch12_str_class.h(23) : see reference to class template instantiation 'std::back_insert_iterator<_Container>' being compiled
with
[
_Container=Vec
]
c:\program files\microsoft visual studio 9.0\vc\include\iterator(32) : error C2039: 'const_reference' : is not a member of 'Vec'
with
[
T=char
]
c:\program files\microsoft visual studio 9.0\vc\include\iterator(32) : error C2061: syntax error : identifier 'const_reference'
c:\program files\microsoft visual studio 9.0\vc\include\iterator(33) : error C2805: binary 'operator =' has too few parameters
c:\program files\microsoft visual studio 9.0\vc\include\iterator(33) : error C2333: 'std::back_insert_iterator<_Container>::operator =' : error in function declaration; skipping function body
with
[
_Container=Vec
]
Generating Code...
Compiling...
ch11_Vec_class.cpp
Generating Code...
Compiling...
ch11_sec1_the_vec_class.cpp
Generating Code...
You'll have to post some code.
file called "ch11_Vec_class.h"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef ch11_VEC_CLASS
#define ch11_VEC_CLASS

#include <memory>

using std::allocator;

template <class T> class Vec {
public:
	
	typedef T* iterator;
	typedef const T* const_iterator;
	typedef size_t size_type;
	typedef T value_type;

	Vec() { create(); }														
	explicit Vec(size_type n, const T& val = T()) { create(n,val); }		

	size_type size() const { return limit - data; }

	T& operator[](size_type i ) { return data[i]; }
	const T& operator[](size_type i) const { return data[i]; }

	iterator begin() { return data; }
	const_iterator begin() const { return data; }

	iterator end() { return limit; }
	const_iterator end() const { return limit; }

	Vec(const Vec& v) { create(v.begin(), v.end()); }				

	Vec& operator=(const Vec&);								

	~Vec() { uncreate(); }

	void push_back(const T& val)
	{
		if (avail == limit)
			grow();
		unchecked_append(val);
	}

private:
	iterator data;		
	iterator avail;		
	iterator limit;		
		
	allocator<T> alloc;	

	void create();
	void create(size_type, const T&);
	void create(const_iterator, const_iterator);

	void uncreate();

	void grow();
	void unchecked_append(const T&);
};

template <class T> Vec<T>& Vec<T>::operator=(const Vec& rhs)
{
	if (&rhs != this) {
	
		uncreate();
	
		create(rhs.begin(), rhs.end());
	}
	return *this;
}

#endif /* ch11_VEC_CLASS */ 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
file called "ch11_Vec_class.cpp"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "ch11_Vec_class.h"

template <class T> void Vec<T>::create()
{
	data = avail = limit = 0;
}

template <class T> void Vec<T>::create(size_t n, const T& val)
{
	data = alloc.allocate(n);
	limit = avail = data + n;
	uninitialized_fill(data, limit, val);
}

template <class T> void Vec<T>::create(const_iterator i, const_iterator j)
{
	data = alloc.allocate(j - i);
	limit = avail = uninitialized_copy(i, j, data);
}

template <class T> void Vec<T>::uncreate()
{
	if (data) {
		iterator it = avail;
		while (it != data)
			alloc.destroy(--it);

		alloc.deallocate(data, limit - data);													
	}
	
	data = limit = avail = 0;
}

template <class T> void Vec<T>::grow()
{
	size_type new_size = max(2 * (limit - data), ptrdiff_t(1));

	iterator new_data = alloc.allocate(new_size);
	iterator new_avail = uninitialized_copy(data, avail, new_data);

	uncreate();

	data = new_data;
	avail = new_avail;
	limit = data + new_size;
}

template <class T> void Vec<T>::unchecked_append(const T& val)
{
	alloc.construct(avail++, val);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
file called "ch12_Str_class.h"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef ch12_STR_CLASS
#define ch12_STR_CLASS

#include <algorithm>
#include <cstring>
#include <cctype>
#include "ch11_Vec_class.h"


class Str {
public:
	typedef Vec<char>::size_type size_type;

	Str() { }

	Str(size_type n, char c) : data(n, c) { }

	Str(const char* cp) {
		std::copy(cp, cp + std::strlen(cp), std::back_inserter(data));
	}

	template <class In> Str(In b, In e) {
		std::copy(b, e, std::back_inserter(data));
	}
	
	char& operator[] (size_type i) { return data[i]; }			
	const char& operator[] (size_type i) const { return data[i]; }
	
private:
	Vec<char> data;
};

#endif	/* ch12_STR_CLASS */ 

Last edited on
Please let me know if you need some further code. And thank you so much for your help.
Well the problem it seems is that you are attempting to create a container a la the STL containers with the expectation that your Vec class can work with the STL algorithms and iterations, whereas in fact you are missing quite a few requirements.

For example, you must have a reference type, const_reference type, pointer type, to name the obvious ones I can think of off the top of my head.

Also worthy of note is that your assignment operator is not exception safe.

Thank you for your help.

Just as a fyi, the class I am creating is from the book Accelerated C++ by Andrew Koenig and Barbara Moo and mainly to follow along with their examples in chapters 11 & 12.

I *think* I fixed the reference and const_reference issues with the following:

typedef T& reference;
typedef const T& const_reference;

Can you please help me with the pointer_type and assignment operator and some of the other issues? As you can tell, I am learning and this will be a big assistance. Thanks!
typedef T* pointer;

An exception-safe assignment operator is more than I can take on at the moment. I can give you examples and you'll have to figure out how to make yours exception safe.

Exception safe assignment operators are typically implemented with the copy-swap idiom. Here is a trivial example:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Foo {
    int x;
    int y;
  public:
    Foo& operator=( Foo rhs )  // Take a _copy_ of the rvalue
    {
        // Swap all the elements
        std::swap( x, rhs.x ); 
        std::swap( y, rhs.y );
        return *this;
    }
};


This works provided that std::swap() does not throw. [Note that the std::swap template won't throw for POD-types, but there is no guarantee for user-defined types. You have to write swap() for your
user-defined types if you want to make the guarantee].

Exception safety simply means that the assignment operator leaves the "assigned-to" object in a valid, known state if an exception occurs. In the case above, provided that swap does not throw, the only other thing that can throw is Foo's copy constructor. If it does, then the "assigned-to" object is left unchanged.

In your assignment operator, you do "uncreate() followed by create()". Your uncreate() method deallocates memory and runs destructors; your create method allocates memory and calls constructors. Any of those operations may throw, meaning that if an exception occurs, your "assigned-to" object will be left in some unknown, possibly even invalid state.

Thanks! Your trivial example is very helpful. I think I can create an exception safe operator using the concepts you detailed in it. If you have the time and are willing, please let me know any other suggestions. Thank you again.
Topic archived. No new replies allowed.