Solved

__closure equivalent in vc++

Posted on 2014-10-01
3
299 Views
Last Modified: 2014-10-02
In the Embarcadero world, we could create a typedef like this

typedef double (__closure *CalVmFuncType) (int, unsigned);

where __closure is defined as : The __closure keyword is used to declare a special type of pointer to a member function. In standard C++, the only way to get a pointer to a member function is to use the fully qualified member name

Could someone tell me (or show me) the equivalent keyword in the Visual C++ environment (I am using Vs2013).
0
Comment
Question by:BrianDumas
3 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
ID: 40355318
Check out http://www.newty.de/fpt/index.html ("The Function Pointer Tutorials") and http://www.newty.de/fpt/fpt.html#chapter2 ("The Syntax of C and C++ Function Pointers") in particular. In your particular case - and if '()' is indeed a class' member - that would be

typedef double (YourClass::*CalVmFuncType) (int, unsigned);

Open in new window


If it is not a member of any class but a standalone function, you can just use

typedef double (*CalVmFuncType) (int, unsigned);

Open in new window

0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 40356237
this might be a bit advanced and contrived but if you are interested in C++ 0x and like lambdas then have a read on how they can be used as fn ptrs

Especially the section on Making Delegates with Lambdas might interest you

http://www.cprogramming.com/c++11/c++11-lambda-closures.html
0
 
LVL 33

Assisted Solution

by:sarabande
sarabande earned 250 total points
ID: 40357463
to add to above comments:

pointer to member functions are not very comfortable in c++ and require a weird syntax for definition (as you can see by the typedef posted by jkr). unfortunately, calling the function by pointer is even worse:

CalVmFuncType myFunction = &YourClass::CalVmFunc1;
....
(m_pYourClass->*myFunction )(123, 0xffffffff);

Open in new window

the compiler needs both an instance of the class the function is member of and the pointer to function.

the __closure in the Embarcadero makes the syntax as easy as with normal function pointers as long as you don't leave the class context. it simply uses the 'this' pointer automatically and you don't have to care for a pair of object and function but only for the function pointer.

in visual c++ you have some alternatives even if you don't make the step to c++0x as suggested by trinitrotoluene.

(A) you can use functors, which are little helper classes with overloaded operator().
  functor objects can be called like function and often passed instead of a (normal) function pointer and allow to
  parameterize the function when constructing the functor.

 
class MyClass
  { 
    int m_fc;
  public:
    MyClass(int fc) : m_fc(fc) {}
    double MyFunc(int i, unsigned int ui) { return (m_fc == 1)? MyFunc1(i, ui) : MyFunc2(i, ui); }
    double MyFunc1(int i, unsigned int ui)
    {
        std::ostringstream oss;
        oss << i << '.' << (int)ui;
        return atof(oss.str().c_str());
    }
    double MyFunc2(int i, unsigned int ui)
    {
        if (i == 0) i = 1;
        double d = ui/i; 
        return d;
    }
  };


struct MyFunctor
{
    MyClass & m_mc;
       
    MyFunctor(MyClass & mc) : m_mc(mc) {}
    double operator() (int i, unsigned ui)
    {  
        return m_mc.MyFunc(i, ui);
    }
  };

  void f()
  {
    MyFunctor mf(MyClass(2));
    double d = mf(-123, 999); 
  }

Open in new window

 
   the functor could have any parameters in the constructor, so you also could pass
   a base class pointer if you want, what then allows to call virtual member functions
   as well.

   see http://stackoverflow.com/questions/356950/c-functors-and-their-uses for more info.

(B) you also could define static member functions and pass the object as first argument:

 
// forward declaration
  class MyClass;

  // typedef a function pointer to global function
  typedef double (*CalVmFuncType) (MyClass * pObj, int, unsigned);

  class MyClass
  {
     ....
  public:
    // member function to call
    double MyCalVmFunc1(int n, unsigned int ui);  
    double MyCalVmFunc2(int n, unsigned int ui);  
    static double CalVmFunc1(MyClass * pObj, int n, unsigned int ui)
    {
           return pObj->MyCalVmFunc1(n, ui);
    }
   static double CalVmFunc2(void * pObj, int n, unsigned int ui)
   {  ...

Open in new window

  with the above you can do

 
CalVmFuncType myFunction = &MyClass::CalVmFunc1;
  ....
  MyClass myObj(...);
  double d = myFunction(&myObj, 123, 0xffffffff);

Open in new window

  you see the code is slightly less cryptic. and there is another advantage. you could have
   the pObj as base class pointer instead of MyClass pointer. then you could make the
   member functions virtual functions. if the function is a callback function you might use
   the same technique and pass the this pointer of your class object together with the
   function pointer (for that you normally can use an additional void pointer argument.
   when the callback was called the object pointer was passed back and could be
   casted to a valid object pointer).

Sara
0

Featured Post

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When you try to extract and to view the contents of a Microsoft Update Standalone Package (MSU) for Windows Vista, you cannot extract the files from the MSU. Here we are going to explain how to extract those hotfix details without using any third pa…
In this article, I will show you HOW TO: Perform a Physical to Virtual (P2V) Conversion the easy way from a computer backup (image).
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Windows 8 came with a dramatically different user interface known as Metro. Notably missing from that interface was a Start button and Start Menu. Microsoft responded to negative user feedback of the Metro interface, bringing back the Start button a…

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question