473,387 Members | 1,669 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,387 software developers and data experts.

cannot dynamic_cast 't' (of type 'void*') to type 'struct mom::object*' (source is not a pointer to class)

I just do not understand this error.
Am I misusing dynamic_cast ?

What I want to do is to have a single template construct
(with no optional argument) so that it works for whatever
T I want to use it with. Now, if that T happens to be some
subclass of a known base class (object, in this case), I
want to perform some extra stuff ...

I've read Faq#35, and the most natural solution would have
been to write the function as a non static envelope member
parameterized on T, but the reason the code is "out-line" is
because of a circular dependency that would be introduced
between object & envelope if I was to let envelope.hpp know
about the innards of object.hpp.

I solved this by using a "free standing", non templatized regular
function, whose definition, inside envelope.cpp is now allowed
to include object.hpp ...

/Users/verec/Tools/trunk/Style/tests/build/mom/../../../src/common/mom/envelope.cpp:68:
error:

cannot dynamic_cast 't' (of type 'void*') to type
'struct mom::object*' (source is not a pointer to class)

file envelope.hpp

namespace mom {
// ...
void construct(void * t) ; // <-- decl

template <typename T> struct envelope {
// ...

static void * cast(T * t) {

return dynamic_cast<void *>(t) ;

}

// ...

envelope(T * q = 0) : body(q) {
// ...
construct(cast(body)) ;

}
} ;
}

file envelope.cpp

#include "mom/envelope.hpp"
#include "mom/object.hpp"

namespace mom {

// ...
void
construct(void * t) {
object * o = dynamic_cast<object *>(t) ; // <-- defn: where
GCC 4.0 chokes.
if (o) {
o->construct() ;
}
}
}

for completeness ...
file opbject.hpp

namespace mom {
struct object {
object() {}

virtual
~object() {}

virtual void
construct() {}
// ...
} ;
}

Any idea what I'm doing wrong?

Many thanks
--
JFB

Aug 7 '05 #1
5 8672

verec wrote:
I just do not understand this error.
Am I misusing dynamic_cast ?
yes. you can't cast from void* because the compiler can't know what
type the object really is. you can only cast from polymorphic types (in
which case, the compiler typically looks at the v-table pointer to
determine what type the object really is).

What I want to do is to have a single template construct
(with no optional argument) so that it works for whatever
T I want to use it with. Now, if that T happens to be some
subclass of a known base class (object, in this case), I
want to perform some extra stuff ...

I've read Faq#35, and the most natural solution would have
been to write the function as a non static envelope member
parameterized on T, but the reason the code is "out-line" is
because of a circular dependency that would be introduced
between object & envelope if I was to let envelope.hpp know
about the innards of object.hpp.

I solved this by using a "free standing", non templatized regular
function, whose definition, inside envelope.cpp is now allowed
to include object.hpp ...

/Users/verec/Tools/trunk/Style/tests/build/mom/../../../src/common/mom/envelope.cpp:68:
error:

cannot dynamic_cast 't' (of type 'void*') to type
'struct mom::object*' (source is not a pointer to class)

file envelope.hpp

namespace mom {
// ...
void construct(void * t) ; // <-- decl
void construct(void * t);
void construct(object * t);

problem solved?

template <typename T> struct envelope {
// ...

static void * cast(T * t) {

return dynamic_cast<void *>(t) ;
the cast is completely unnecessary, T* converts to void* implicitly,
where T is not a function or member function type. of course, if you
convert to void*, you lose all type info, which probably isn't a good
thing.

you might want to consider boost::any, however that probably won't help
with your overall design. www.boost.org
}

// ...

envelope(T * q = 0) : body(q) {
// ...
construct(cast(body)) ;

}
} ;
}

file envelope.cpp

#include "mom/envelope.hpp"
#include "mom/object.hpp"

namespace mom {

// ...
void
construct(void * t) {
object * o = dynamic_cast<object *>(t) ; // <-- defn: where
GCC 4.0 chokes.
if (o) {
o->construct() ;
}
}
}

for completeness ...
file opbject.hpp

namespace mom {
struct object {
object() {}

virtual
~object() {}

virtual void
construct() {}
// ...
} ;
}

Any idea what I'm doing wrong?
quite frankly, any program design which includes such an incredibly
generic object base class usually smells of a bad design. you can't do
anything with this object other than construct or destroy it. you'd
have to cast to a more specific derived class type to do anything
useful with it, which trying to figure out what derived class to cast
to is generally a "fun" exercise. C++ doesn't have an object base class
for a reason.
Many thanks
--
JFB


Aug 7 '05 #2
* Alipha:

static void * cast(T * t) {

return dynamic_cast<void *>(t) ;


the cast is completely unnecessary, T* converts to void* implicitly,
where T is not a function or member function type.


Given the rest of the code one might think so, but this is a very special
case: a dynamic cast to void* gives a pointer to the most derived object.
E.g., T could here be an interface that t, an object instantiated from C,
implements. The dynamic cast gives a pointer to the C object. The problem
is doing something useful with that void* pointer. There is no dynamic cast
back again, so except for comparing pointer values (which is the only
portable usage I know of) the client code needs to know the type C.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Aug 7 '05 #3
On 2005-08-07 18:28:24 +0100, "Alipha" <al*****@hotmail.com> said:
verec wrote:
I just do not understand this error.
Am I misusing dynamic_cast ?
yes. you can't cast from void* because the compiler can't know what
type the object really is. you can only cast from polymorphic types (in
which case, the compiler typically looks at the v-table pointer to
determine what type the object really is).


Thanks. So the cast to void * is one way street, even though *I am*
telling the compiler what I expect it to cast to: why is dynamic_cast
supposed to return 0 or even throw bad_cast if not for the possibility
I may have lied to the compiler... Well, I'l learn to live with that
I suppose...

On 2005-08-07 18:39:38 +0100, al***@start.no (Alf P. Steinbach) said:
the cast is completely unnecessary, T* converts to void* implicitly,
where T is not a function or member function type.


Given the rest of the code one might think so, but this is a very special
case: a dynamic cast to void* gives a pointer to the most derived object.
E.g., T could here be an interface that t, an object instantiated from C,
implements. The dynamic cast gives a pointer to the C object. The problem
is doing something useful with that void* pointer.


Store them in a map, no matter what branch of the derivation was used.
There is no dynamic cast back again


This was the most unexpected event for today :-( I'll have to rethink
how I'm going to cope with that.

Many thanks to both.
--
JFB

Aug 7 '05 #4
> Thanks. So the cast to void * is one way street, even though *I am*
telling the compiler what I expect it to cast to: why is dynamic_cast
supposed to return 0 or even throw bad_cast if not for the possibility
I may have lied to the compiler... Well, I'l learn to live with that
I suppose...


If you are so confident you can use reinterpret_cast. I wouldn't...

Ben
Aug 8 '05 #5
On 2005-08-08 11:46:18 +0100, "benben" <be******@hotmail.com> said:
Thanks. So the cast to void * is one way street, even though *I am*
telling the compiler what I expect it to cast to: why is dynamic_cast
supposed to return 0 or even throw bad_cast if not for the possibility
I may have lied to the compiler... Well, I'l learn to live with that
I suppose...

If you are so confident you can use reinterpret_cast. I wouldn't...


Many thanks for the idea. It turns out that I was just confused about
the need to:
- forward declare to avoid circular dependencies
- have every single template definition inside a header file so that
the compiler could instantiate it as and when.

The code now reads:

file envelope.hpp

namespace mom {
// ...
struct object ; // forward decl
void construct_if(object * o) ;

// ...
template <typename T> struct envelope {
// ...
envelope(T * q = 0) : body(q) {
// ...
construct_if(dynamic_cast<object *>(body)) ;

}
} ;
}

file envelope.cpp

#include "mom/envelope.hpp"
#include "mom/object.hpp"

namespace mom {

// ...
void
construct_if(object * o) {
if (o) {
o->construct() ;
}
}
}

And I'm happy :-)

Many Thanks
--
JFB

Aug 15 '05 #6

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

Similar topics

11
by: Marcin Kalicinski | last post by:
Hi, How to convert a type inside a template from pointer to type to type itself? struct S { }; template<class It> void f(It begin, It end) { // When called from g(), It::value_type is a...
4
by: LordHog | last post by:
Hello all, I am having a little problem getting my (void *) assignment to work correctly. Basically it is some code for a circular queue buffer I am trying to implement, but getting the...
2
by: Maurice | last post by:
Hi, Is it legal to cast from void(*)(A*) to void(*)(B*)? Is it legal to cast from struct Derived{Base b; ...} to struct Base? I'm trying to get some inheritance and polymorphism in C and I...
2
by: Max | last post by:
When you add an event handler to some object you need to specify the function to call when the event occurs. Suppose there is a class TesterClosed() which is called whenever the Tester is closed....
16
by: Abhishek | last post by:
why do I see that in most C programs, pointers in functions are accepted as: int func(int i,(void *)p) where p is a pointer or an address which is passed from the place where it is called. what...
5
by: Johs32 | last post by:
I have a struct "my_struct" and a function that as argument takes a pointer to this struct: struct my_struct{ struct my_struct *new; }; void my_func(struct my_struct *new); I have read...
8
by: Neha | last post by:
Hi all Its seems bit silly que but pleasee explan me why this error is coming ? and what will be the solution if i want void * to be intilaize by struct * and this code is puerly in C. --...
14
by: andreyvul | last post by:
g++ says a reinterpret cast from void* is disallowed; however, all I'm trying to do is de-capsulate a void* argument that holds the pointer to a class (and static_cast forces cast constructor) any...
5
by: alan | last post by:
Hello world, I'm trying to implement a (hopefully portable!) tagged pointer class. Basically, I have my own allocator which will ensure alignment at 8- byte boundaries (where "byte" is "size of...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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...

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.