Template parameter binding: early versus late

S

Stu

I have some C++ code that has been running on various versions of
Microsoft Visual C++ for several years. I am now trying to get it
running on Unix, specifically gcc. I have hit two snags. The first is
quite simple: #pragma once is obsolete. Was this replaced by
something better, or do we have to go back to the old #ifndef nnn_h
trick?

The second problem is that I did something that is apparently not
allowed by the ISO standard. Consider the following code:

template<class TContainer>
void WriteSequence(
std::eek:stream& aStream,
const TContainer& aContainer)
{
bool isFirst = true;
TContainer::const_iterator iter;
for (iter=aContainer.begin(); iter!=aContainer.end(); iter++)
{
if (isFirst)
isFirst = false;
else
aStream<<",";
aStream<<*iter;
}
}


Yeah, I know: useless code, but it does illustrate an issue. The hope
was that if WriteSequence<T> were instantiated with a type T that
defined T::const_iterator then all would be well. If T didn't, then
there would be a compile error at the point of instantiation. MS VC++
was apparently cool with this, which implies that it binds its
templates to code later than does gcc. From what I have heard, gcc is
almost always a closer implementation of the standard, so I assume this
is nonstandard.

If this can't be done within the standard, is there some nice legal way
of doing the same thing? The sticking point seems to be that each of
the containers is a separate class with no common superclass that
defines const_iterator.
 
A

Arne Adams

Stu said:
The second problem is that I did something that is apparently not
allowed by the ISO standard. Consider the following code:

template<class TContainer>
void WriteSequence(
std::eek:stream& aStream,
const TContainer& aContainer)
{
bool isFirst = true;
TContainer::const_iterator iter;
typename required here:
typename TContainer::const_iterator iter;
for (iter=aContainer.begin(); iter!=aContainer.end(); iter++)
{
if (isFirst)
isFirst = false;
else
aStream<<",";
aStream<<*iter;
}
}


Yeah, I know: useless code, but it does illustrate an issue. The hope
was that if WriteSequence<T> were instantiated with a type T that
defined T::const_iterator then all would be well. If T didn't, then
there would be a compile error at the point of instantiation. MS VC++
was apparently cool with this, which implies that it binds its
templates to code later than does gcc. From what I have heard, gcc is
almost always a closer implementation of the standard, so I assume this
is nonstandard.
The typename is needed because TContainer::const_iterator could very well be
the name of a data member or member function for some TContainer.
To make the life of compiler writers (a bit) easier the standard introduced
the rule that a name in a template that depends on a template parameter and
that names a type must be preceeded with typename.


Arne
 

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,054
Latest member
TrimKetoBoost

Latest Threads

Top