Typedef'ing a subtype of a template

  • Thread starter Ney André de Mello Zunino
  • Start date
N

Ney André de Mello Zunino

Hello.

It's been about a year since I last did some C++ programming. I am now
paying the price as I try to catch up with it.

The following is the initial snippet of a simple program I am working
on. I don't know or remember how one goes about typedef'ing a subtype of
a template.

#include <string>
#include <map>

namespace {
using namespace std;

typedef map<string, int> Word_Map;
typedef Word_Map::value_type Word_Map_Pair;
}

The g++ compiler is not happy about the second typedef. I have tried
adding /typename/ to it, but the compiler then yells at me for using
/typename/ outside of a template.

Could anyone help a rusty fellow programmer?

Thank you,
 
R

red floyd

Ney said:
Hello.

It's been about a year since I last did some C++ programming. I am now
paying the price as I try to catch up with it.

The following is the initial snippet of a simple program I am working
on. I don't know or remember how one goes about typedef'ing a subtype of
a template.

#include <string>
#include <map>

namespace {
using namespace std;

typedef map<string, int> Word_Map;
typedef Word_Map::value_type Word_Map_Pair;
}

The g++ compiler is not happy about the second typedef. I have tried
adding /typename/ to it, but the compiler then yells at me for using
/typename/ outside of a template.

Could anyone help a rusty fellow programmer?

I see nothing wrong with your code. Is this the entire fragment? What
compiler are you using?
 
I

Ian Collins

Ney said:
Hello.

It's been about a year since I last did some C++ programming. I am now
paying the price as I try to catch up with it.

The following is the initial snippet of a simple program I am working
on. I don't know or remember how one goes about typedef'ing a subtype of
a template.

#include <string>
#include <map>

namespace {
using namespace std;

typedef map<string, int> Word_Map;
typedef Word_Map::value_type Word_Map_Pair;
}

The g++ compiler is not happy about the second typedef. I have tried
adding /typename/ to it, but the compiler then yells at me for using
/typename/ outside of a template.
How can it when you don't?

Post a complete example.
 
N

Ney André de Mello Zunino

red said:
I see nothing wrong with your code. Is this the entire fragment? What
compiler are you using?

The compiler is g++ (GCC) 4.1.3. And here's a complete program. In its
current form, it _will_ compile. However, substituting the second
typedef for the third one will cause the compilation error when the
priority_queue /Word_Queue/ is instantiated in main().

#include <string>
#include <map>
#include <queue>
#include <vector>

namespace {
using namespace std;

typedef map<string, int> Word_Map;
// typedef Word_Map::value_type Word_Map_Pair;
typedef pair<string, int> Word_Map_Pair;

struct Word_Map_Pair_Comparator {
bool operator()(const Word_Map_Pair& pair_1,
const Word_Map_Pair& pair_2) {
return pair_1.second >= pair_2.second;
}
};

typedef priority_queue<Word_Map_Pair, vector<Word_Map_Pair>,
Word_Map_Pair_Comparator> Word_Queue;
}

int main(int argc, char* argv[]) {
Word_Queue word_queue;
}

Thank you,
 
A

Alf P. Steinbach

* Ney André de Mello Zunino:
The compiler is g++ (GCC) 4.1.3. And here's a complete program. In its
current form, it _will_ compile. However, substituting the second
typedef for the third one will cause the compilation error when the
priority_queue /Word_Queue/ is instantiated in main().

#include <string>
#include <map>
#include <queue>
#include <vector>

namespace {
using namespace std;

typedef map<string, int> Word_Map;
// typedef Word_Map::value_type Word_Map_Pair;

The commented definition would effectively define (note the const, which
makes the type non-assignable)

typedef pair< string const, int > Word_Map_Pair;

By the way, note that your naming convention is formally invalid.

An underscore can't be followed by an uppercase letter, it is reserved
for implementation names.

typedef pair<string, int> Word_Map_Pair;

struct Word_Map_Pair_Comparator {
bool operator()(const Word_Map_Pair& pair_1,
const Word_Map_Pair& pair_2) {
return pair_1.second >= pair_2.second;
}
};

typedef priority_queue<Word_Map_Pair, vector<Word_Map_Pair>,
Word_Map_Pair_Comparator> Word_Queue;
}

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

Please don't include things such as unused arguments that cause warnings.

Aim for 100% clean compiles.

Word_Queue word_queue;
}

This is OK.

However, using the non-assignable version of Word_Map_Pair as a
container element type is formally Undefined Behavior, and a good
compiler + library implementation will then issue diagnostics.


Cheers, & hth.,

- Alf
 
N

Ney André de Mello Zunino

Alf P. Steinbach escreveu:
The commented definition would effectively define (note the const, which
makes the type non-assignable)

typedef pair< string const, int > Word_Map_Pair;

I couldn't realize (remember) that the /map::value_type/ typedef is of
the form pair said:
By the way, note that your naming convention is formally invalid.

An underscore can't be followed by an uppercase letter, it is reserved
for implementation names.

You know, I've always been a "camelCaser", of the kind who thought
underscores were really ugly. It was only *very* recently that I allowed
myself to have a different appreciation of underscores. The
experimentation is still in progress.

As for the implementation-reserved forms, I thought they concerned only
the cases where an uppercase letter follows an underscore at the
beginning of an identifier. But anyway, rusty as I am now, it's very
likely that I am missing something.
int main(int argc, char* argv[]) {

Please don't include things such as unused arguments that cause warnings.

Aim for 100% clean compiles.

Sorry about that. The code posted is a trimmed-down version of a
slightly larger program where command line arguments are indeed used. I
just forgot to remove them here.
However, using the non-assignable version of Word_Map_Pair as a
container element type is formally Undefined Behavior, and a good
compiler + library implementation will then issue diagnostics.

Thanks, Alf. Got it now.

Cheers,
 
B

Bo Persson

Ney André de Mello Zunino wrote:
:: Alf P. Steinbach escreveu:
::
:::: namespace {
:::: using namespace std;
::::
:::: typedef map<string, int> Word_Map;
:::: // typedef Word_Map::value_type Word_Map_Pair;
:::
::: The commented definition would effectively define (note the
::: const, which makes the type non-assignable)
:::
::: typedef pair< string const, int > Word_Map_Pair;
::
:: I couldn't realize (remember) that the /map::value_type/ typedef
:: is of the form pair<const Key, T>. Thanks for pointing it out.
::
::: By the way, note that your naming convention is formally invalid.
:::
::: An underscore can't be followed by an uppercase letter, it is
::: reserved for implementation names.
::
:: You know, I've always been a "camelCaser", of the kind who thought
:: underscores were really ugly. It was only *very* recently that I
:: allowed myself to have a different appreciation of underscores. The
:: experimentation is still in progress.
::
:: As for the implementation-reserved forms, I thought they concerned
:: only the cases where an uppercase letter follows an underscore at
:: the beginning of an identifier.

You are correct.

Alf is probably mixing the rules up - a double underscore is reserved
anywhere in the identifier. Underscore uppercase only at the
beginning.

_Reserved_identifier
Reserved__identifier
Non_Reserved_Identifier


Bo Persson
 
A

Alf P. Steinbach

* Bo Persson:
Ney André de Mello Zunino wrote:
:: Alf P. Steinbach escreveu:
::
:::: namespace {
:::: using namespace std;
::::
:::: typedef map<string, int> Word_Map;
:::: // typedef Word_Map::value_type Word_Map_Pair;
:::
::: The commented definition would effectively define (note the
::: const, which makes the type non-assignable)
:::
::: typedef pair< string const, int > Word_Map_Pair;
::
:: I couldn't realize (remember) that the /map::value_type/ typedef
:: is of the form pair<const Key, T>. Thanks for pointing it out.
::
::: By the way, note that your naming convention is formally invalid.
:::
::: An underscore can't be followed by an uppercase letter, it is
::: reserved for implementation names.
::
:: You know, I've always been a "camelCaser", of the kind who thought
:: underscores were really ugly. It was only *very* recently that I
:: allowed myself to have a different appreciation of underscores. The
:: experimentation is still in progress.
::
:: As for the implementation-reserved forms, I thought they concerned
:: only the cases where an uppercase letter follows an underscore at
:: the beginning of an identifier.

You are correct.

Alf is probably mixing the rules up - a double underscore is reserved
anywhere in the identifier. Underscore uppercase only at the
beginning.

_Reserved_identifier
Reserved__identifier
Non_Reserved_Identifier

Well, yeah, you're right. Additionally identifiers starting with
underscore are reserved in the global namespace.

Cheers,

- Alf
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top