f



how to inject some code inside function.

Hello. I have the following (simplified) code in the body of a
function:

if (myvar.get_type() == "int")
     dosomething<int> f(func);
     f(myvar.get());
else if (myvar.get_type() == "double")
    dosomething<double> f2(func);
    f(myvar.get());


What I would like to do is to be able to remove the ifs to be able to
inject code
inside this body but from outside the body of the function, maybe with
partial specializations,
but I don't know how to achieve this. Could anyone help me, please?


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

0
german
2/14/2009 4:50:42 PM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8506) is leader. Post Follow

8 Replies
357 Views

Similar Articles

[PageSpeed] 39

On Feb 14, 5:50 pm, german diago <germandi...@gmail.com> wrote:
> Hello. I have the following (simplified) code in the body of a
> function:
>
> if (myvar.get_type() == "int")
>      dosomething<int> f(func);
>      f(myvar.get());
> else if (myvar.get_type() == "double")
>     dosomething<double> f2(func);
>     f(myvar.get());
>
> What I would like to do is to be able to remove the ifs to be able to
> inject code
> inside this body but from outside the body of the function, maybe with
> partial specializations,
> but I don't know how to achieve this. Could anyone help me, please?

You want to call a function on (or with) an object, and would like
the behavior of the function to be selected based on its type?

That's a virtual function.

Template specializations only work at compile time, but clearly your
code is deciding behavior at runtime.  If myvar's type isn't
polymorphic, either it should be, or it should hold a data member
that is that implements the functionality that is changeable.
You might also consider using the visitor pattern, but that's still
an elaboration on a virtual function solution.

If you don't use virtual functions, you'll end up simulating them (or
simulating something very much like them) in your own code, one way
or
another.  You might use templates to help write this simulation, but
I'm not sure how you could escape it entirely.  You might use a
lookup-
table, keyed by your type code, mapped to a function (polymorphic or
otherwise callable object (function pointer, binder, etc), but that's
still essentially a virtual function.

Chris


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

0
Chris
2/15/2009 7:35:57 AM
{ Top-posting is discouraged in this group. See the FAQ for posting guidelines. 
-mod }

You can overload the function.
Create the 2 identical functions with the same name, but with
different dummy argument types:

e.g. void function ( int ) {...} and void function ( double ) {...}

Depending on the actual argument passed in the function call, the
program will automatically choose which function to use.

I hope this is what your looking for, and sorry for the bad english.

On Feb 14, 7:50 pm, german diago <germandi...@gmail.com> wrote:
> Hello. I have the following (simplified) code in the body of a
> function:
>
> if (myvar.get_type() == "int")
>      dosomething<int> f(func);
>      f(myvar.get());
> else if (myvar.get_type() == "double")
>     dosomething<double> f2(func);
>     f(myvar.get());
>
> What I would like to do is to be able to remove the ifs to be able to
> inject code
> inside this body but from outside the body of the function, maybe with
> partial specializations,
> but I don't know how to achieve this. Could anyone help me, please?

{ Edits: quoted banner removed. -mod }


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

0
ISO
2/15/2009 7:37:59 AM
On 14 f�v, 23:50, german diago <germandi...@gmail.com> wrote:
> Hello. I have the following (simplified) code in the body of a
> function:
>
> if (myvar.get_type() == "int")
>      dosomething<int> f(func);
>      f(myvar.get());
> else if (myvar.get_type() == "double")
>     dosomething<double> f2(func);
>     f(myvar.get());
>
> What I would like to do is to be able to remove the ifs to be able to
> inject code
> inside this body but from outside the body of the function

template<typename F>
typename F::result_type visit(F f)
{
     if(myvar.get_type() == "int")
         return f(myvar.get<int>());
     if(myvar.get_type() == "double")
         return f(myvar.get<double>());

     assert(0);
}

Boost.Variant does that, in an even better way.
I recommend you use it.


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

0
Mathias
2/15/2009 7:41:02 AM
german diago wrote:
> Hello. I have the following (simplified) code in the body of a
> function:
> 
> if (myvar.get_type() == "int")
>      dosomething<int> f(func);
>      f(myvar.get());
> else if (myvar.get_type() == "double")
>     dosomething<double> f2(func);
>     f(myvar.get());
> 
> 
> What I would like to do is to be able to remove the ifs to be able to
> inject code
> inside this body but from outside the body of the function, maybe with
> partial specializations,
> but I don't know how to achieve this. Could anyone help me, please?
> 
> 

Obviously you think whatever the above is will be a solution to a
problem you have. Rather than ask us how to implement a solution you
would be better off telling us what problem you are trying to solve.

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

0
Francis
2/15/2009 7:41:15 AM
On 15 feb, 14:41, Francis Glassborow
<francis.glassbo...@btinternet.com> wrote:
> german diago wrote:
> > Hello. I have the following (simplified) code in the body of a
> > function:
>
> > if (myvar.get_type() == "int")
> >      dosomething<int> f(func);
> >      f(myvar.get());
> > else if (myvar.get_type() == "double")
> >     dosomething<double> f2(func);
> >     f(myvar.get());
>
> > What I would like to do is to be able to remove the ifs to be able to
> > inject code
> > inside this body but from outside the body of the function, maybe with
> > partial specializations,
> > but I don't know how to achieve this. Could anyone help me, please?
>
> Obviously you think whatever the above is will be a solution to a
> problem you have. Rather than ask us how to implement a solution you
> would be better off telling us what problem you are trying to solve.
>
> --
>       [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]
>       [ comp.lang.c++.moderated.    First time posters: Do this! ]

I think I explained myself in a very bad way, sorry. What I'm looking
for (if it's possible),
is a way to avoid this:

void operator()(value v1, ...)
     if (v1.get_type() == "int")
       dosomething<int>(f)
     else if...
}


I'm doing this because I want to do argument marshalling. For basic
types, this is not a problem.
The problem is that I want to register new types at runtime, and I'd
like them to be marshalled too.
I mean, using function call operator with this prototype:

void operator()(value v1, value v2, value v3);

  Where value holds any registered type in my type system,
I want to be able to add new types at runtime, for use with this kind
of function. And to use it, I must
do argument marshalling inside the function. Anyone knows how to do
this? It's being quite difficult for me.
Thanks in advance.


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

0
german
2/15/2009 6:08:41 PM
german diago wrote:
> On 15 feb, 14:41, Francis Glassborow
> <francis.glassbo...@btinternet.com> wrote:
>> german diago wrote:
>>> Hello. I have the following (simplified) code in the body of a
>>> function:
>>> if (myvar.get_type() == "int")
>>>      dosomething<int> f(func);
>>>      f(myvar.get());
>>> else if (myvar.get_type() == "double")
>>>     dosomething<double> f2(func);
>>>     f(myvar.get());
>>> What I would like to do is to be able to remove the ifs to be able to
>>> inject code
>>> inside this body but from outside the body of the function, maybe with
>>> partial specializations,
>>> but I don't know how to achieve this. Could anyone help me, please?
>> Obviously you think whatever the above is will be a solution to a
>> problem you have. Rather than ask us how to implement a solution you
>> would be better off telling us what problem you are trying to solve.

> 
> I think I explained myself in a very bad way, sorry. What I'm looking
> for (if it's possible),
> is a way to avoid this:
> 
> void operator()(value v1, ...)
>      if (v1.get_type() == "int")
>        dosomething<int>(f)
>      else if...
> }
> 
> 
> I'm doing this because I want to do argument marshalling. For basic
> types, this is not a problem.
> The problem is that I want to register new types at runtime, and I'd
> like them to be marshalled too.
OK now we know the problem.

> I mean, using function call operator with this prototype:
> 
> void operator()(value v1, value v2, value v3);

The first problem is that that must be a member function of some class.
The second problem is that you cannot add overloads or new template
specialisations at runtime.  C++ does not permit the creation of new
types at runtime so your type system must be effectively complete before
  execution of the program. I say effectively complete because there is
a little wriggle room to allow for dynamic libraries.

> 
>   Where value holds any registered type in my type system,
> I want to be able to add new types at runtime, for use with this kind
> of function. And to use it, I must
> do argument marshalling inside the function. Anyone knows how to do
> this? It's being quite difficult for me.

Given that the type must exist before translation has been completed I
think you need a member template. Something along the lines of:

class example {
public:
   template<typename parameter>
    void operator() (parameter p1, parameter p2, parameter p3);
// rest of definition
};

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

0
Francis
2/16/2009 9:15:05 AM
On Feb 16, 2:08 am, german diago <germandi...@gmail.com> wrote:
> What I'm looking
> for (if it's possible),
> is a way to avoid this:
>
> void operator()(value v1, ...)
>      if (v1.get_type() == "int")
>        dosomething<int>(f)
>      else if...
>
> }
>
> I'm doing this because I want to do argument marshalling. For basic
> types, this is not a problem.
> The problem is that I want to register new types at runtime, and I'd
> like them to be marshalled too.
> I mean, using function call operator with this prototype:
>
> void operator()(value v1, value v2, value v3);
>
>   Where value holds any registered type in my type system,
> I want to be able to add new types at runtime, for use with this kind
> of function. And to use it, I must
> do argument marshalling inside the function. Anyone knows how to do
> this? It's being quite difficult for me.

With a map.

typedef std::map<std::string, boost::function<void()> > DispatchMap;
DispatchMap dispatchMap;

// fill the map as necessary

void operator()(value v1)
{
     DispatchMap::iterator f = dispatchMap.find(v1.get_type());
     if (f != dispatchMap.end())
         f(v1);
}

Yechezkel Mett


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

0
Yechezkel
2/16/2009 9:18:23 AM
Hi!

german diago schrieb:
> void operator()(value v1, ...)
>      if (v1.get_type() == "int")
>        dosomething<int>(f)
>      else if...
> }
> 
> 
> I'm doing this because I want to do argument marshalling. For basic
> types, this is not a problem.
> The problem is that I want to register new types at runtime, and I'd
> like them to be marshalled too.

You must either know all the types at compile time, or the new types
must implement marshalling themselves.

Something like:

void marshall(string type, value v)
{
	dosomething<type>(v);
}

will never be possible. You cannot invent new code at runtime.
(Theoretically at runtime you could automatically generate some code,
invoke the compiler to generate a shared object/DLL and load that DLL at
runtime. But you need the source code of the types in order to inspect
their members. And even then, you cannot automatically assign the
correct meaning to these members, whether they need to be marshalled or
not, or whatever)

Back to the problem:
I guess you want to marshall object, either to store them in a file or
database, or you want to marshall objects in order to transfer them over
network and then call a remote function with them.

First can be achived using for example Boost.Serialization:
http://www.boost.org/doc/libs/1_38_0/libs/serialization/doc/index.html

Second can be schived using for example ZeroC ICE:
http://www.zeroc.com/

I hope this helps.
Frank

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

0
Frank
2/16/2009 4:21:46 PM
Reply: