Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::any and const pointers
From: Dominique Devienne (ddevienne_at_[hidden])
Date: 2009-12-02 15:37:49


On Wed, Dec 2, 2009 at 1:03 PM, James C. Sutherland
<James.Sutherland_at_[hidden]> wrote:
> On Dec 2, 2009, at 11:24 AM, Dominique Devienne wrote:
>> On Wed, Dec 2, 2009 at 10:55 AM, James C. Sutherland
> Actually, this runs just fine (at least on my mac running g++ 4.2.1).

Ah, sorry, you're right of course, since with const T t, when passed
an int*, the const is applied to the pointer and not the int, so it's
only a int*const instead of a const int* (or int const *). Given that
typeid(int *const) == typeid(int*), that why you can get it as a
"int*" later on.

This time I double-checked by printing the types in your set() method
and verifying that typeid(int*) == typeid(int*const).

C:\C++>any_cast.exe
typeid(T) = int (.H)
typeid(t) = int (.H)
typeid(T) = int * (.PAH)
typeid(t) = int * (.PAH)

C:\C++>typeid_test.exe
...
typeid(int*) = int * (.PAH)
typeid(const int*) = int const * (.PBH)
typeid(int*const) = int * (.PAH)
typeid(const int*const) = int const * (.PBH)
...

> Also, the following compiles and runs fine:
>        int m = get<int>(p,"int");
> This is because you cannot force const semantics on a copy.

You're right again. Should have run my typeid tests again to refresh
my memory before I answered your post :)

C:\C++>g++ -O2 typeid_test.cpp
C:\C++>a.exe
typeid(int) = int (i)
typeid(const int) = int (i)
....
C:\C++>cl /Od /EHsc /nologo typeid_test.cpp
typeid_test.cpp
C:\C++>typeid_test.exe
typeid(int) = int (.H)
typeid(const int) = int (.H)
...

> I came up with a way to get const references out (using boost::ref), but can't get const pointers guaranteed.  I fear that you are right about this not being possible.

As you mention, can't force const on values, and references are just
like values as far as typeid() is concerned:

typeid(Base) = class Base (.?AVBase@@)
typeid(Base&) = class Base (.?AVBase@@)
typeid(const Base) = class Base (.?AVBase@@)
typeid(const Base&) = class Base (.?AVBase@@)

OTOH, with pointers:

typeid(mutab_pt) = class Point3d (.?AVPoint3d@@)
typeid(const_pt) = class Point3d (.?AVPoint3d@@)
typeid(ptr_mutab_pt) = class Point3d * (.PAVPoint3d@@)
typeid(ptr_const_pt) = class Point3d const * (.PBVPoint3d@@)

with

  Point3d mutab_pt(2,3,4);
  const Point3d const_pt(3,4,5);
  Point3d* ptr_mutab_pt = &mutab_pt;
  const Point3d* ptr_const_pt = &const_pt;

Bottom line is, if typeid() of what you put in doesn't match typeid()
of what you're trying to get it as, it will fail, and a pointer to T
will not be any_cast'able as a pointer to const T, or vice-versa (you
can't even get the T* as a T const*, despite the valid implicit
conversion, you must first get it as a T*, and then rely on the normal
implicit pointer conversion). --DD


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net