473,405 Members | 2,300 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Namespace in a typedef

Sometimes it is useful to assign class names to types that are
primitives even if they add no more functionality, at the very least to
be able to determine which constants apply to a type:

typedef int Address;
void test(Address address) { ... }
const Address ADDRESS1 = 0xff, ADDRESS2 = 0x3f;

Of course, this method is type unsafe since any int can be passed in
but to the reader it is at least clear that ADDRESS1 and ADDRESS2 are
associated with argument 1 in function test(). The alternative, more
typesafe way is to:

class Address {
public:
operator=(int address) ...
operator int() ...
.. all other operators

static const Address ADDRESS1, ADDRESS2;
private:
Address(int address) ...
};

This creates an enumeration that can behave as an integer. If the items
in the enum don't need actual values, then one can just compare the
address of the items for identity. To be even more safe, replace the
casting operator with a method. Unfortunately, this method works much
better in Java than in C++ as the constants must be defined in a
separate file, a large list of functions must be overloaded, and
remembering to compare by address is painful. This implementation is
also too large for a realtime system with memory constraints. GCC is
also nice enough to print a warning that it has no public constructors.

So my question is, I like the method 1 for creating a type but I have
no good place to put the constants for it and was wondering if anyone
had any ideas. What I'm looking for is something like:

class Address : public int {
// constants
};

Of course this doesn't work. I thought maybe something like this would
work:

typedef int Address;
namespace Address { // constants }

But unfortunately it doesn't. Any ideas on how to accomplish this?

Jul 23 '05 #1
3 2301

balor wrote:
Sometimes it is useful to assign class names to types that are
primitives even if they add no more functionality, at the very least to be able to determine which constants apply to a type:

typedef int Address;
void test(Address address) { ... }
const Address ADDRESS1 = 0xff, ADDRESS2 = 0x3f;

Of course, this method is type unsafe since any int can be passed in
but to the reader it is at least clear that ADDRESS1 and ADDRESS2 are
associated with argument 1 in function test(). The alternative, more typesafe way is to:
.... use enums, but you can also use ...
class Address {
public:
operator=(int address) ...
operator int() ...
.. all other operators

static const Address ADDRESS1, ADDRESS2;
private:
Address(int address) ...
};

This creates an enumeration that can behave as an integer.
If the items in the enum don't need actual values, then
one can just compare the address of the items for identity.
To be even more safe, replace the casting operator with
a method. Unfortunately, this method works much
better in Java than in C++ as the constants must be
defined in a separate file, a large list of functions
must be overloaded, and remembering to compare by address
is painful. "Remembering to compare by address"? What's stopping you
from providing a sane operator==? At the very least it can
return this==&rhs, or else it can do o normal value comparison.
This implementation is also too large for a realtime
system with memory constraints.


FUD. There is no reason at all why it would generate more
code. Everything can be inlined, producing identical
assembly.
In fact, because of typesafety, a good compiler could
even detect the range of possible values and generate
more efficient code.

Regards,
Michiel Salters

Jul 23 '05 #2
I'd use enums if namespace weren't problematic.

enum A {A1, A2};
void function() { A a = A::A1; }

Unfortunately, A1 and A2 are defined in the global namespace and one is
not allowed to scope into A. One could try:

namespace A {
enum {A1, A2};
}

This method works but then A1/A2 don't have a type. Another solution
is:

namespace A {
enum B {A1, A2};
}

This last method works but the type requires a scope which adds no
value. I don't understand why the standard defines constants in the
namespace of the enum.

Even if I had an enum that didn't pollute its namespace, there are
other concerns. The enum isn't type safe like a class nor expandable
like one, although one could convert it to a class without affecting
existing code.

On the other issue, it is true if functions were inlined in the
class-based enum the functions would take no space but what about
constants? There has to be a location in memory allocated to compare by
address whereas with a static const int the compiler can inline the int
everywhere it is used. I suppose the amount of memory consumed by
constants is trivial but the amount of code required to define the type
is rather large. Perhaps I shouldn't be defining classes that behave as
integers in the first place.

I can see how type safety improves documenting of code and reduces bugs
but how would a compiler exploit type safety to produce more efficient
code?

Thanks for the help.

Jul 23 '05 #3
One thing I just thought of that has promise is:

class A {
public:
operator int() { return (int)this; }
static const A a, b;
};

const A A::a;
const A A::b;

Unfortunately, GCC requires that variables be initialized. I fail to
see the value in this requirement as the address of the object alone is
all that I'm interested in. The following works though:

const A A::a(a);
const A A::b(b);

Its a stupid workaround though.

Jul 23 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: trying_to_learn | last post by:
im in the primary stages of learning C++. The book im learning from says Dont use using namespace.. directive in header file However im trying to make the following header file.I need to include...
10
by: lallous | last post by:
Hello I noticed that when I use #define inside a namespace then this #define only works when prefixed with the namespace name. Is this behaviour standard or just compiler specific? I use...
6
by: Patrick Guio | last post by:
Dear all, I try to compile the following code in two ways: * using one compilation unit: g++ main.cpp base.cpp -o main * creating a library for the class factory. g++ -c -o base.o...
5
by: Enos Meroka | last post by:
Hallo, I am a student doing my project in the university.. I have been trying to compile the program using HP -UX aCC compiler, however I keep on getting the following errors. ...
6
by: SpOiLeR | last post by:
Why doesn't following code compile? Problem line is commented in code. ---------------------- Cut here------------------------------- #include <iostream> #include <list> #include <string> ...
20
by: Patrick Guio | last post by:
Dear all, I have some problem with insertion operator together with namespace. I have a header file foo.h containing declaration of classes, typedefs and insertion operators for the typedefs in...
4
by: red floyd | last post by:
What is the linkage of a namespace scope typedef? Is it internal or external? 3.5 is unclear on this. In other words, is the following program, consisting of translation units a.cpp and...
3
by: toton | last post by:
Hi, Is it possible to have a class level namespace opening instead of file level . Something like this, I have a long namespace like namespace com { namespace my_company{ namespace...
5
by: Michael | last post by:
Hi All, I've wasted heaps of time today trying to get some code I copied from a text to compile. I have cut it down to the following couple of lines which demonstrate the core of the problem: ...
4
by: michael | last post by:
Hi all, why if I can use std::vector<int>::iterator variable; can I not use using std::vector<int>::iterator;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.