Click here to Skip to main content
Click here to Skip to main content

typeof operator implementation

, 6 Aug 2004
Rate this:
Please Sign up or sign in to vote.
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! Smile | :)
  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. Smile | :)
  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

Share

About the Author

Goran Mitrovic

Croatia Croatia
No Biography provided

Comments and Discussions

 
Generalusing boost 1.34.1 PinmemberVictor Morozko10-Aug-07 2:31 
GeneralRe: using boost 1.34.1 PinmemberGoran Mitrovic10-Aug-07 2:36 
QuestionWhy not use something like this? PinsussThiago R. Adams9-Sep-04 18:44 
AnswerRe: Why not use something like this? PinmemberGoran Mitrovic10-Sep-04 0:15 
GeneralRe: Why not use something like this? Pinmemberthiago_adams10-Sep-04 3:37 
GeneralRe: Why not use something like this? PinmemberGoran Mitrovic10-Sep-04 4:07 
GeneralRe: Why not use something like this? Pinmemberthiago_adams10-Sep-04 6:03 
GeneralNice work Pinsussbpe13-Aug-04 15:36 
Generalawesome PinmemberTweety8-Aug-04 10:45 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150327.1 | Last Updated 7 Aug 2004
Article Copyright 2004 by Goran Mitrovic
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid