Departments


We Have Mail


Letters to the editor may be sent via email to cujed@cmp.com, or via the postal service to Letters to the Editor, C/C++ Users Journal, 1601 W. 23rd St., Ste 200, Lawrence, KS 66046-2700.


Dear CUJ,

In the article "An Improved Variant Type Based on Member Templates," by Fernando Cacciola (CUJ, October 2000) the author at one place stated:

...I thought about adding a method of the form:

string type_name() const
{return typeid(*data).name();}

but this method would return strings such as “variant_t::Impl<int>”, revealing implementation details...

Although, his statement is certainly true, I have found a simple solution to the problem of revealing implementation details of class variant_t. With a few additions it is possible to get the exact name of type T. In Listing 4 of the article, three lines should be added [broken here to fit column layout]:

1) In the public part of struct ImplBase:

virtual std::string
TypeName() const = 0;

2) In the public part of struct Impl:

virtual std::string TypeName() const
{ return typeid(T).name(); }

3) In the public part of class variant_t:

std::string type_name() const
{ return data->TypeName(); }

I have changed the test0 function from the article, to demonstrate the effects of these changes, as shown in Listing 1.

Using VC++ 6 with STLport4, the output of this function looks like this (first and last line omitted, lines broken to fit column layout):

2 is of type int
3.14 is of type double
This is a string is of type
class _STL::basic_string<char,class
_STL::char_traits<char>,
class _STL::allocator<char> >

As I have stated before, this solution returns the exact type of T. This can be seen on all three lines, but the third line is a glaring example of the consequences: it now shows implementation details of T. To solve this kind of situation, a solution similar to one proposed in "Classes for Reading and Writing Parameter Blocks" (by Andrew Queisser in the same October 2000 issue) could be devised.

A small side effect of the solution I propose here is that the is_type method and the family of is_type_as methods could all be rewritten to use the type_name method. Instead of Impl<T>, type T could now be used in comparisons. Besides obvious (but very small) gains/losses — seven characters less to compare (gain) with one extra call to virtual function (loss) — I suspect that the largest gains (if any) would depend on the compiler and its implementation of the type_id operator.

Sincerely,

Ivan Erceg
ierceg@harseim.com

Fernando Cacciola replies:

Dear Ivan,

I received the comments you sent to CUJ regarding the article. Your solution is great! I’ve changed my code accordingly and tested it under C++ Builder 5.0 and gcc 2.95.2 (under the cygwin port). I also changed the implementation of is_type as you suggested.

By the way, I noticed the cross-assignment in the code you sent As you probably discovered it has the effect of changing the ‘inner type’ of the variant_t lvalue (since the internal Impl<T> is just copied). I have added a new test5 function to variant_test.cpp to show this effect.

Thank you for this improvement!

Fernando Cacciola
Sierra s.r.l.
fcacciola@fibertel.com.ar

We have uploaded Fernando’s latest update to our online source archives for the October 2000 issue. It is also available in this month’s archive in the letters.zip file. — mb


Dear CUJ,

The November 2000 article, "Creating Truly Maintainable Class Factories," by Early Ehlinger, was well written. And the author provided several useful utility macros and classes to access DLLs.

What he failed to mention were the "normal" problems encountered with using DLLs in the Windows environment. We are all aware of the version problems that DLLs can create. And it’s one more thing to distribute with the application. I would strongly argue that the support trouble the DLLs would cause are far worse the minor maintenance problems associated with a more traditional approach to class factories.

At the very least, the DLL wrapper classes provided should include version information so that the application could exit gracefully when the class in the DLL doesn’t match the version of the class the application is using.

Listing 2 shows three useful macros that make the traditional methods and static libraries almost as easy as the DLL method. And, rather than linear searches, using integer IDs and a switch statement is much more efficient, and could be encapsulated in macros instead of the string method illustrated here.

Bob Lorezen

Your approach is certainly more portable, and it does keep us out of DLL Hell, where all of us have been at one time or another. However, the DLL approach might be less cumbersome than yours if the factory needs to create a large variety of objects. Although Early only alluded to it, his article was inspired by the need to create C++ objects from XML files, where the number of different element types could conceivably be very large. I do like your idea of putting version checking code in the DLL wrappers. Thanks for writing. — mb


Dear Sirs,

I have a general programming comment concerning checking times.

In the November 2000 issue, in Mike Scanlon’s excellent article "Secure Web-Based Licencing," he suggests protecting against back clocking by means of a simple comparison:

if (lTime < lCurrentTime)
   ...

This is too harsh. There are legitimate reasons for changing the system time, such as correcting the clock when it is a few minutes too fast, or when traveling across time zones with a notebook, or when changing back from daylight saving time. In all these cases many users make some common mistakes, such as doing it around midnight and forgetting to change the date, so in general I recommend a 26-hour tolerance.

I hope such a margin will not create too big a loophole in the scheme.

Best regards,

Jony Rosenne