By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,952 Members | 1,935 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,952 IT Pros & Developers. It's quick & easy.

novice template query

P: n/a
bb
Hi,
On compiling the following simple template backed by 'std::vector', get
the following compile time error:

----- Compilation error ----------

tc2.h: In member function 'void MyArray<T>::display()':
tc2.h:36: error: expected `;' before 'ivi'
tc2.h:37: error: 'ivi' was not declared in this scope
tc2.h: In member function 'void MyArray<T>::display() [with T =
std::basic_string<char, std::char_traits<char>, std::allocator<char>
]': tc2.h:49: instantiated from here
tc2.h:36: error: dependent-name 'std::vector<T,std::allocator<_CharT>::iterator' is parsed as a non-type, but instantiation yields a type tc2.h:36: note: say 'typename std::vector<T,std::allocator<_CharT>::iterator' if a type is meant


------ Code --------------------------

template<typename T>
class MyArray {
public:
MyArray();
~MyArray();
void append(const T& item);
void display();
private:
std::vector<T> *v;
};

template<typename T>
MyArray<T>::MyArray() {
v = new std::vector<T>();
}

template<typename T>
MyArray<T>::~MyArray() {
delete v;
}

template<typename T>
void MyArray<T>::append(const T& item) {
v->push_back(item);
}

template<typename T>
void MyArray<T>::display() {

std::vector<T>::iterator ivi; // *** I know the issue is HERE ***
for(ivi = v->begin(); ivi != v->end(); ++ivi)
std::cout << *ivi << std::endl;
}

int main(int argc, char** argv) {

MyArray<std::string> ma1;
ma1.append("Test1");
ma1.append("Test2");

ma1.display();
}

------- Code ends -----------------------------------

Any comments/help please?

Thanks.

Apr 12 '06 #1
Share this Question
Share on Google+
11 Replies


P: n/a
bb wrote:
Hi,
On compiling the following simple template backed by 'std::vector', get
the following compile time error:

----- Compilation error ----------

tc2.h: In member function 'void MyArray<T>::display()':
tc2.h:36: error: expected `;' before 'ivi'
tc2.h:37: error: 'ivi' was not declared in this scope
tc2.h: In member function 'void MyArray<T>::display() [with T =
std::basic_string<char, std::char_traits<char>, std::allocator<char>

What happens if you include the required headers, <string> and <vector>?

Everything else looks to be OK.

--
Ian Collins.
Apr 12 '06 #2

P: n/a
bb
Hi,
The problem here is the iterator definition that the compiler doesn't
like.

template<typename T>
void MyArray<T>::display() {
std::vector<T>::iterator ivi; // *** I know the issue is
HERE ***
for(ivi = v->begin(); ivi != v->end(); ++ivi)
std::cout << *ivi << std::endl;
}

If I change it to be specific e.g. std::string as follows, it compiles
and runs ok. However, my question is how to keep it generic?.

std::vector<std:string>::iterator ivi;

Cheers.

Apr 12 '06 #3

P: n/a
bb wrote:
Hi,
The problem here is the iterator definition that the compiler doesn't
like.

template<typename T>
void MyArray<T>::display() {
std::vector<T>::iterator ivi; // *** I know the issue is
HERE *** typename std::vector<T>::iterator ivi; for(ivi = v->begin(); ivi != v->end(); ++ivi)
std::cout << *ivi << std::endl;
}

If I change it to be specific e.g. std::string as follows, it compiles
and runs ok. However, my question is how to keep it generic?.

std::vector<std:string>::iterator ivi;

Cheers.


iterator is a dependent type. The compiler doesn't know that iterator
is a type. Use typename. as shown above.
Apr 12 '06 #4

P: n/a
bb <mu**********@gmail.com> wrote:
----- Compilation error ---------- [snip] tc2.h:36: error: dependent-name 'std::vector<T,std::allocator<_CharT>
::iterator' is parsed as a non-type, but instantiation yields a type tc2.h:36: note: say 'typename std::vector<T,std::allocator<_CharT>
::iterator' if a type is meant


------ Code --------------------------

[snip] std::vector<T>::iterator ivi; // *** I know the issue is HERE ***


Your error message tells you how to fix the error; however, VS .NET 2003
compiled it as-is (after #include'ing <iostream>, <vector>, and
<string>).

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Apr 12 '06 #5

P: n/a
bb
Hi,
You are simply spot on. Thanks, it works.

I have another query in the same context...

template<typename T>
void showMe(T& t) {
std::cout << t << std::endl;
}

template<typename T>
void MyArray<T>::display2() {
for_each(v->begin(),v->end(),showMe<T>);
}

The above works fine as long as showMe() is a non-member template
function.

However, if I change showMe() to be a member of the template as
follows, it doesn't compile. I suspect the problem is in the calling
syntax. Any comments please?

template<typename T>
void MyArray<T>::showMe(T& t) {
std::cout << t << std::endl;
}

Thanks again.

Apr 12 '06 #6

P: n/a
Tip: Start a new thread for a new question.

bb wrote:
However, if I change showMe() to be a member of the template as
follows, it doesn't compile.


That's because a member function has a 'this'. The for_each (as called) has
no capacity to pass the 'this' in.

There are helper templates that bind the 'this' to the function object
passed to algorithms like for_each().

But why do you need the function to be a member? If it won't use the 'this',
or any members of its object, inside the function, then don't bother to
pass it in.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 12 '06 #7

P: n/a
bb
> Tip: Start a new thread for a new question.

Apologies, will do from next time.
That's because a member function has a 'this'. The for_each (as called) has
no capacity to pass the 'this' in. There are helper templates that bind the 'this' to the function object
passed to algorithms like for_each().
Precisely, can u throw some more light on this, please?
But why do you need the function to be a member? If it won't use the 'this',
or any members of its object, inside the function, then don't bother to
pass it in.


True. This is, probably, an over simplified version and not a good
example, hmmm.

Apr 12 '06 #8

P: n/a
bb
Thanks, yes, i realized it a bit late.

Apr 12 '06 #9

P: n/a
bb wrote:
Thanks, yes, i realized it a bit late.


Realized what?

Brian

--
Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header.
Apr 12 '06 #10

P: n/a

"Marcus Kwok" <ri******@gehennom.invalid> wrote in message
news:e1**********@news-int2.gatech.edu...
bb <mu**********@gmail.com> wrote:
----- Compilation error ---------- [snip]
tc2.h:36: error: dependent-name 'std::vector<T,std::allocator<_CharT>
::iterator' is parsed as a non-type, but instantiation yields a type

tc2.h:36: note: say 'typename std::vector<T,std::allocator<_CharT>
::iterator' if a type is meant


------ Code --------------------------

[snip]
std::vector<T>::iterator ivi; // *** I know the issue is HERE

***
Your error message tells you how to fix the error; however, VS .NET 2003
compiled it as-is (after #include'ing <iostream>, <vector>, and
<string>).

--
Marcus Kwok
Replace 'invalid' with 'net' to reply


Hmm, vc6.0sp4 couldn't compile the code with header and 'typename' added,
#include <vector>
#include <iostream>

template<typename T>
class MyArray {
public:
MyArray();
~MyArray();
void append(const T& item);
void display();
private:
std::vector<T> *v;
};

template<typename T>
MyArray<T>::MyArray() {
v = new std::vector<T>();
}

template<typename T>
MyArray<T>::~MyArray() {
delete v;
}

template<typename T>
void MyArray<T>::append(const T& item) {
v->push_back(item);
}

template<typename T>
void MyArray<T>::display() {

typename std::vector<T>::iterator ivi; // *** I know the issue is HERE
***
for(ivi = v->begin(); ivi != v->end(); ++ivi)
std::cout << *ivi << std::endl;
}

int main(int argc, char** argv) {

MyArray<std::string> ma1;
ma1.append("Test1");
ma1.append("Test2");

ma1.display();
}
Compiling...
template1.cpp
E:\Win32\tests\template1.cpp(45) : warning C4508: 'main' : function should
return a value; 'void' return type assumed
E:\Win32\tests\template1.cpp(35) : error C2679: binary '<<' : no operator
defined which takes a right-hand operand of type 'class
std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> >' (or there is no acceptable conversio
n)
e:\program files\microsoft visual studio\vc98\include\xmemory(59) :
while compiling class-template member function 'void __thiscall
MyArray<class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > >::display(vo
id)'
Error executing cl.exe.

template1.obj - 1 error(s), 1 warning(s)
Apr 18 '06 #11

P: n/a
Fei Liu wrote:
"Marcus Kwok" <ri******@gehennom.invalid> wrote in message
news:e1**********@news-int2.gatech.edu...
bb <mu**********@gmail.com> wrote:
----- Compilation error ----------

[snip]
tc2.h:36: error: dependent-name 'std::vector<T,std::allocator<_CharT>
::iterator' is parsed as a non-type, but instantiation yields a type
tc2.h:36: note: say 'typename std::vector<T,std::allocator<_CharT>
::iterator' if a type is meant
------ Code --------------------------

[snip]
std::vector<T>::iterator ivi; // *** I know the issue is HERE

***
Your error message tells you how to fix the error; however, VS .NET 2003
compiled it as-is (after #include'ing <iostream>, <vector>, and
<string>).

--
Marcus Kwok
Replace 'invalid' with 'net' to reply


Hmm, vc6.0sp4 couldn't compile the code with header and 'typename' added,

[code redacted]


VC6 is pre-standard and has horrible template support. Upgrade to a
modern compiler.
Apr 18 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.