Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to determine the type of data at run time?

2 views
Skip to first unread message

jungleman

unread,
Sep 14, 2010, 9:55:40 AM9/14/10
to
Hi all,

I'm using a library (opencv actually) provided by others. There's a
class called "Mat", in which stored chunk of data with many types.
Also, there's a member in the Mat class to indicate which data the
class stores.

I want to use the class more intelligently to avoid checking series
data types in running time.

for example, in the original codes:
switch(type_flag) {
case INT_TYPE:
break;
case FLOAT_TYPE:
break;
... ...
}

How can I avoid this?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Dobi

unread,
Sep 15, 2010, 8:05:39 AM9/15/10
to
On 14 Sep., 15:55, jungleman <ustcrevolution...@gmail.com> wrote:
> Hi all,
>
> I'm using a library (opencv actually) provided by others. There's a
> class called "Mat", in which stored chunk of data with many types.
> Also, there's a member in the Mat class to indicate which data the
> class stores.
>
> I want to use the class more intelligently to avoid checking series
> data types in running time.
>
> How can I avoid this?
Hi jungleman,
depends on what you are doing with the matrices. You could write a
wrapper class around cv::Mat for holding it, perhaps with template
specialisation for the different data types.
Regards,
Dobi

Ulrich Eckhardt

unread,
Sep 15, 2010, 12:28:49 PM9/15/10
to
jungleman wrote:
> I'm using a library (opencv actually) provided by others. There's a
> class called "Mat", in which stored chunk of data with many types.
> Also, there's a member in the Mat class to indicate which data the
> class stores.

This is commonly called a "variant" type.

> I want to use the class more intelligently to avoid checking series
> data types in running time.
>
> for example, in the original codes:
> switch(type_flag) {
> case INT_TYPE:
> break;
> case FLOAT_TYPE:
> break;
> ... ...
> }
>
> How can I avoid this?

I'd suggest a visitor pattern as one approach. I'd also take a look at =
the
documentation of Boost.Variant, which is a library for such variant =
types
that already provides some of the necessary code for visitors.

Uli

--
Sator Laser GmbH
Gesch=C3=A4ftsf=C3=BChrer: Thorsten F=C3=B6cking, Amtsgericht Hamburg HR =
B62 932

Mathias Gaunard

unread,
Sep 15, 2010, 12:28:30 PM9/15/10
to
On Sep 14, 2:55=A0pm, jungleman <ustcrevolution...@gmail.com> wrote:
> Hi all,
>
> I'm using a library (opencv actually) provided by others. There's a
> class called "Mat", in which stored chunk of data with many types.
> Also, there's a member in the Mat class to indicate which data the
> class stores.
>
> I want to use the class more intelligently to avoid checking series
> data types in running time.
>
> for example, in the original codes:
> switch(type_flag) {
> =A0 =A0case INT_TYPE:
> =A0 =A0 =A0break;
> =A0 =A0case FLOAT_TYPE:
> =A0 =A0 =A0break;
> =A0 =A0... ...

>
> }
>
> How can I avoid this?

You could do

template<typename F>
typename F::result_type visit(F f, Mat& m)
{
switch(m.type_flag)
{
case INT_TYPE:
return f(*static_cast<int*>(m.void_ptr));

case FLOAT_TYPE:
return f(*static_cast<float*>(m.void_ptr));

...
}
}

then

struct my_visitor
{
typedef void result_type;

void operator()(int i)
{
std::cout << "it's an int " << i << std::endl;
}

void operator()(float f)
{
std::cout << "it's a float " << f << std::endl;
}
};

visit(m, my_visitor());

Now, you can also define the visitor inline, but that requires some
pretty advanced trickery or C++0x lambdas.

Matthew Collett

unread,
Sep 16, 2010, 12:54:12 PM9/16/10
to
In article <632e2996-76f6-44b0...@s24g2000pri.googlegroups.com>,
jungleman <ustcrevo...@gmail.com> wrote:

> I'm using a library (opencv actually) provided by others. There's a
> class called "Mat", in which stored chunk of data with many types.
> Also, there's a member in the Mat class to indicate which data the
> class stores.
>
> I want to use the class more intelligently to avoid checking series
> data types in running time.
>
> for example, in the original codes:
> switch(type_flag) {
> case INT_TYPE:
> break;
> case FLOAT_TYPE:
> break;
> ... ...
> }

This is a textbook application of polymorphism.
Define an abstract base class, let's say MatBase, which contains a Mat (or a
pointer to one). For each data type, define a derived class: IntMat, FloatMat,
etc. Finally, define a factory function CreateMat, which takes a Mat as
argument and spits out the appropriate derived class wrapper.
The factory function will still have to contain a switch on type_flag, but
thereafter all type-dependent processing can be done in virtual functions
declared but not defined in BaseMat and implemented for each data type in the
corresponding derived class, so that no switching is required.

Best wishes,
Matthew

--
http://homepages.ihug.co.nz/~m_collett

Dragan Milenkovic

unread,
Sep 22, 2010, 12:29:18 AM9/22/10
to

Actually, I would call this a textbook anti-application of polymorphism.
It may work for operations such as "transpose" or
"invert", maybe "multiply by an integer", but there is not much
useful stuff you can be put into virtual functions (unless you
use dynamic casting as a simple alternative to a switch)...
Others have already suggested using a variant and a visitor.

If necessary and applicable, polymorphic design might come in
a layer above this one.

--
Dragan

Larry Evans

unread,
Sep 25, 2010, 7:22:27 PM9/25/10
to
On Sep 21, 11:29 pm, Dragan Milenkovic <dra...@plusplus.rs> wrote:
> On 09/16/2010 06:54 PM, Matthew Collett wrote:
>
>
>
> > In article<632e2996-76f6-44b0-85ef-2f67baae8...@s24g2000pri.googlegroups.com>,
> > jungleman<ustcrevolution...@gmail.com> wrote:
[snip]

> >> I want to use the class more intelligently to avoid checking series
> >>datatypes in running time.

>
> >> for example, in the original codes:
> >> switch(type_flag) {
> >> case INT_TYPE:
> >> break;
> >> case FLOAT_TYPE:
> >> break;
> >> ... ...
> >> }
>
> > This is a textbook application of polymorphism.
> > Define an abstract base class, let's say MatBase, which contains a Mat (or a
> > pointer to one). For eachdatatype, define a derived class: IntMat, FloatMat,

> > etc. Finally, define a factory function CreateMat, which takes a Mat as
> > argument and spits out the appropriate derived class wrapper.
> > The factory function will still have to contain a switch on type_flag, but
> > thereafter alltype-dependent processing can be done in virtual functions
> > declared but not defined in BaseMat and implemented for eachdatatypein the

> > corresponding derived class, so that no switching is required.
>
> Actually, I would call this a textbook anti-application of polymorphism.
[snip]

> Others have already suggested using a variant and a visitor.
[snip]
The visitor pattern:

http://en.wikipedia.org/wiki/Visitor_pattern

was suggested by:

http://groups.google.com/group/comp.lang.c++.moderated/msg/1c3236126f6980c0?hl=en

and that uses polymorphism; hence, I'm not sure it is an example
of an anti-application. Could you further justify this conclusion
in light of the Visitor_pattern?

TIA.

-Larry


--

Ulrich Eckhardt

unread,
Sep 28, 2010, 4:26:19 AM9/28/10
to
Larry Evans wrote:
> On Sep 21, 11:29 pm, Dragan Milenkovic <dra...@plusplus.rs> wrote:
>> On 09/16/2010 06:54 PM, Matthew Collett wrote:
>>> This is a textbook application of polymorphism.
>>> Define an abstract base class, let's say MatBase, which contains a Mat
>>> (or a pointer to one). For eachdatatype, define a derived class:
>>> IntMat, FloatMat, etc.
[...]

>>
>> Actually, I would call this a textbook anti-application of polymorphism.
> [snip]
>> Others have already suggested using a variant and a visitor.
> [snip]
[...]

> and that uses polymorphism; hence, I'm not sure it is an example
> of an anti-application. Could you further justify this conclusion
> in light of the Visitor_pattern?

I'd say that trying to coerce different datatypes into a common interface,
so that you can handle them by just using the interface to the baseclass is
what is wrong. This leads to bloat in the interface (the baseclass needs
everything and the kitchensink) while the implementations become spare and
typically throw a "not supported" exceptions for most functions because
they can't sensibly implement them.

The visitor pattern (a.k.a. double dispatch) is typically implemented using
a single virtual function, so it indeed uses polymorphism. The difference
is that the actual handling is defined by the visitor, and that is supplied
by the code calling the code, not by the implementation of the the actual
types that are being visited. That also means that this caller can make a
decision how it wants to handle different situations and it also avoids the
interface bloat and sparse implementation.


Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932

Dragan Milenkovic

unread,
Sep 29, 2010, 7:25:46 AM9/29/10
to
On 09/26/2010 01:22 AM, Larry Evans wrote:
> On Sep 21, 11:29 pm, Dragan Milenkovic<dra...@plusplus.rs> wrote:
>> On 09/16/2010 06:54 PM, Matthew Collett wrote:
[snip]

>>
>>> This is a textbook application of polymorphism.
>>> Define an abstract base class, let's say MatBase, which contains a Mat (or a
>>> pointer to one). For eachdatatype, define a derived class: IntMat, FloatMat,
>>> etc. Finally, define a factory function CreateMat, which takes a Mat as
>>> argument and spits out the appropriate derived class wrapper.
>>> The factory function will still have to contain a switch on type_flag, but
>>> thereafter alltype-dependent processing can be done in virtual functions
>>> declared but not defined in BaseMat and implemented for eachdatatypein the
>>> corresponding derived class, so that no switching is required.
>>
>> Actually, I would call this a textbook anti-application of polymorphism.
> [snip]
>> Others have already suggested using a variant and a visitor.
> [snip]
> The visitor pattern:
>
> http://en.wikipedia.org/wiki/Visitor_pattern
>
> was suggested by:
>
> http://groups.google.com/group/comp.lang.c++.moderated/msg/1c3236126f6980c0?hl=en
>
> and that uses polymorphism; hence, I'm not sure it is an example
> of an anti-application. Could you further justify this conclusion
> in light of the Visitor_pattern?

I was referring to the quoted design as anti-application. It is
neither a variant nor a visitor pattern. And later I mentioned
that other people have already suggested a good solution.

--
Dragan

0 new messages