Strange thing while using templates

D

drop669

Hi.
I have this piece of code:

=====================================
#include <map>

template <class T> class dict
{
private:

std::map<DWORD, T> m_d;

[ ... ]

void enum_keys_as_dwords (DWORD *out)
{
DWORD *o=out;

for (std::map<DWORD, T>::iterator it=m_d.begin(); it!=m_d.end(); it+
+)
{
*o=it->first;
o++;
};
};
};
=====================================

While compiling this in MinGW, it says:

=====================================
dict:91: error: expected `;' before "it"
=====================================

(line 91 is the line where "for (...)" is located).

I'm really don't know what to do. The problem is probably in using
type T. Where I mistaken?
 
A

Alf P. Steinbach

* (e-mail address removed):
Hi.
I have this piece of code:

=====================================
#include <map>

template <class T> class dict
{
private:

std::map<DWORD, T> m_d;

[ ... ]

void enum_keys_as_dwords (DWORD *out)
{
DWORD *o=out;

for (std::map<DWORD, T>::iterator it=m_d.begin(); it!=m_d.end(); it+
+)
{
*o=it->first;
o++;
};
};
};
=====================================

While compiling this in MinGW, it says:

=====================================
dict:91: error: expected `;' before "it"
=====================================

(line 91 is the line where "for (...)" is located).

I'm really don't know what to do. The problem is probably in using
type T. Where I mistaken?

std::map<DWORD,T>::iterator could in principle be anything, depending on
the type T. So you need to inform the compiler that it's a type. You
do that by adding the word 'typename' in front.

That said, it would be a good idea to use a std::vector instead of a raw
array, and also to make that pure accessor a 'const' member function
(probably 'DWORD' is a Windows API name, but in general, reserve all
uppercase for macros).

Then the function would look like

void get_dwords( std::vector<DWORD>& result ) const
{
typedef typename std::map<DWORD, T>::const_iterator Iterator;
std::vector<DWORD> words;
for( Iterator it = m_d.begin(); it != m_d.end(); ++it )
{
words.push_back( it->first );
}
words.swap( result );
}

Note that this way is in general more exception safe as well, not just
more safe against buffer overflows, null-pointer and other problems
associated with raw arrays and pointers.

You can also provide a convenience wrapper relying on Return Value
Optimization (RVO), which most relevant compilers provide:

std::vector<DWORD> dwords() const
{
std::vector<DWORD> result;
get_dwords( result );
return result;
}

The naming convention employed here is that a command-like function's
name 'get_dwords' says what it does, not how (e.g. enumeration) it does
it, and that a function-like function's name 'dwords' says what result
it delivers. That makes the calling code easier to read and comprehend.

Cheers, & hth.,

- Alf
 
J

Jerry Coffin

Hi.
I have this piece of code:

[ code elided ]
=====================================

While compiling this in MinGW, it says:

=====================================
dict:91: error: expected `;' before "it"
=====================================

(line 91 is the line where "for (...)" is located).

I don't see anything wrong, at least in the code you posted. It's
_possible_ there's a problem in the code you elided, and it's just not
being diagnosed until you reach this point. Quite frankly, that looks
pretty unlikely -- it takes a fairly strange error for the diagnostic to
be delayed into the next function (though mis-matched braces can lead to
it getting confused about where one function ends and the next starts).
Otherwise, it looks to me like a compiler error.
 
R

red floyd

Jerry said:
Hi.
I have this piece of code:

[ code elided ]
=====================================

While compiling this in MinGW, it says:

=====================================
dict:91: error: expected `;' before "it"
=====================================

(line 91 is the line where "for (...)" is located).

I don't see anything wrong, at least in the code you posted. It's
_possible_ there's a problem in the code you elided, and it's just not
being diagnosed until you reach this point. Quite frankly, that looks
pretty unlikely -- it takes a fairly strange error for the diagnostic to
be delayed into the next function (though mis-matched braces can lead to
it getting confused about where one function ends and the next starts).
Otherwise, it looks to me like a compiler error.

As Alf said, OP needs a "typename" ...

for (typename std::map<...>::iterator it = ...)
 
B

Barry

Alf said:
std::map<DWORD,T>::iterator could in principle be anything, depending on
the type T. So you need to inform the compiler that it's a type. You
do that by adding the word 'typename' in front.

alf, did you really ever do that? :)
for (typename std::map<key, value>::iterator it; ...)

the typename issue is only with template parameter

template <class Container>
void f(Contanier const& c)
{
typename Container::iterator it;
}
 
B

Barry

Barry said:
alf, did you really ever do that? :)
for (typename std::map<key, value>::iterator it; ...)

the typename issue is only with template parameter

template <class Container>
void f(Contanier const& c)
{
typename Container::iterator it;
}

Sorry, may bad, I did't see that in the OP
there's a template parameter T
;-)
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top