Click here to Skip to main content
15,884,176 members
Articles / Programming Languages / C++
Article

typeof operator implementation

Rate me:
Please Sign up or sign in to vote.
3.84/5 (8 votes)
6 Aug 20044 min read 77.6K   359   13   9
A typeof operator for Visual C++ 7.1 compiler.

Introduction

One of missing operators in the C++ standard is the typeof operator which returns the type-of given expression. It is often implemeted as a compiler extension, but is still missing from the Visual Studio's C++ compiler (7.1).

Details

However, there are few typeof implementations which could be used, probably all of them based on a very simple, but genious idea introduced by Bill Gibbons (http://www.accu-usa.org/2000-05-Main.html). In a short (feel free to skip this paragraph to the end since it could be hard for you to understand this), each type that will be used with a typeof operation should be separately registered, which partially specializes (by a unique index) a class which contains registered type. Besides it, a new function overload is introduced, which, as a parameter, receives the type that is registering and, as an output, it returns an array that has a size of the unique index used in the previous class.

A typeof operator is now simple to implement: you have an expression you need a type of; call function with the expression as a parameter; calculate a sizeof return value; put the size in a class template parameter and receive a type stored there, which is equal to the expression type! Besides it, all of this is calculated at the compile time, so, no actual function definitions are needed, meaning, no additional code is introduced! A brilliant idea which is useable with very small consequences (every type to be used should be registered and there is a small hit on compiler speed).

Although it's not documented (or I haven't found it in documentation), it appears that Boost's MPL contains a typeof operator implementation that applies to the above pattern:

BOOST_MPL_AUX_REGISTER_TYPE(123, abc);
abc aa1;
BOOST_MPL_AUX_TYPEOF(_, aa1) *aa2 = &aa1;

The drawbacks of Boost' solution, in my opinion, are:

  1. It's undocumented.
  2. The syntax is extemly ugly.
  3. You have to manually feed the registration process with an unique index for every type.
  4. You have to register pointer and constant types separatelly.
  5. You have to use typedefs if you want to register template instances, since colons cannot be put in define macro parameter.
  6. Error messages are non-existent.

I've tried and, hopefully, succeeded in finding workarounds for all listed issues.

Here we go:

  1. You are just looking at it! :)
  2. Syntax is much more clear now! Type registration is done this way:
    register_type hash_table<int, char *> for_typeof;

    ...while the usage is as simple as this:

    hash_table<int, char *> var;
    typeof(&var) ptr = &var;
    for(typeof(var)::iterator it = var.begin(); it != var.end(); it++)

    You can see that the code becomes more readable, you have to type less and, in the case type (especially collection classes) changes, you have to modify only at the one place.

    Note that that if you provide a typedef polluted with pointers, reference or const/volatile modifiers during the registration process, they will be removed for you. Also, feel free to use the typeof operator wherever you want, for local variables, global variables, class members, base classes and so on.

  3. As it can be seen above, you only need a type during the registration! Unique index is provided by a __COUNTER__ macro found in new Visual Studio. However, don't think it makes the implementation trivial - Boost's preprocessor library and template specialization have been heavily used since every usage of the __COUNTER__ macro will give you the different number, while indice had to be used on many places during the registration process!
  4. By using Boost's preprocessor library (which is at the same time very powerful, but very limiting), pointers for the type are automatically registered. A constant TYPEOF_POINTER_LEVELS (defaults to the value of three) defines how many pointers will be registered. In practice, the default value will be more than enough; higher values (50, for example) will make compiler very slow, while the limit is about 80. Also, a const modified at the lowest level will also be registered (an implementation for other combinations would be very complicated).

    To make this more clear, after registration, with default pointer_levels value, you'll be able to work with following types:

    hash_table<int, char *>
    hash_table<int, char *> *
    const hash_table<int, char *> *
    hash_table<int, char *> **
    const hash_table<int, char *> **
    hash_table<int, char *> ***
    const hash_table<int, char *> ***
  5. Fixed, without additional comment. :)
  6. If you'll try to apply the typeof operator to an unregistered type, in a second error message, the typeof_type_not_registered type will be mentioned, which should make more clear what just happened.

I'm looking forward to see comments, improvements, suggestions and more simple solutions!

Requirements

(untested with previous versions)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Croatia Croatia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalusing boost 1.34.1 Pin
_hunter10-Aug-07 1:31
_hunter10-Aug-07 1:31 
GeneralRe: using boost 1.34.1 Pin
Goran Mitrovic10-Aug-07 1:36
Goran Mitrovic10-Aug-07 1:36 
QuestionWhy not use something like this? Pin
thiago_adams9-Sep-04 17:44
thiago_adams9-Sep-04 17:44 
AnswerRe: Why not use something like this? Pin
Goran Mitrovic9-Sep-04 23:15
Goran Mitrovic9-Sep-04 23:15 
GeneralRe: Why not use something like this? Pin
thiago_adams10-Sep-04 2:37
thiago_adams10-Sep-04 2:37 
GeneralRe: Why not use something like this? Pin
Goran Mitrovic10-Sep-04 3:07
Goran Mitrovic10-Sep-04 3:07 
GeneralRe: Why not use something like this? Pin
thiago_adams10-Sep-04 5:03
thiago_adams10-Sep-04 5:03 
GeneralNice work Pin
bpe13-Aug-04 14:36
bpe13-Aug-04 14:36 
Generalawesome Pin
MyBlindy8-Aug-04 9:45
MyBlindy8-Aug-04 9:45 
great article, got my 5!

/* Peace and love,
 *     Tweety
 */

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.