简体   繁体   中英

Syntax for creating a pointer to member function

I'm trying to compile an old code that uses pointers to (non-static) member functions, but it won't compile because the syntax is different now. I can only create a pointer to a function Foo by typing &Bar::Foo , which didn't use to be the case (simply typing Foo would create a member pointer).

When was this syntax added and is there a way to allow the old syntax in VisualStudio to avoid modifying the old code?

Here's a random example, which used to compile:

class Foo
{
public:
  int Bar(int x)
  {
    return x + 2;
  }

  Foo();
};
int (Foo::*f)(int);
Foo::Foo()
{
  f = Bar; // error, have to use f = &Foo::Bar now
}

You don't specify in your question, but whenever I hear the words "the syntax is different," I assume you are migrating from Visual C++ 6 to a newer version of Visual Studio.

The long and short of it is; Visual C++ 6 does not use "standards-compliant C++." Migrating from Visual C++ 6 to any other modern compiler will cause many syntax errors, and will take some effort to migrate into "compliance." You'll just have to suck it up and make the syntax changes.

Off-hand; I don't have a source to back me up, but I would be willing to bet that your function pointer syntax falls into this category.

The good news is; once you've done it, pretty much all the rest of the modern compilers in the world will work with standards-compliant code, so you should only ever have to do this once.

Update:

I did a quick search and found at least one source which seems to confirm the MSVC6 behavior:

"Some compilers (most notably MSVC 6 and 7) will let you omit the &, even though it is non-standard and confusing. More standard-compliant compilers (eg, GNU G++ and MSVC 8 (aka VS 2005)) require it, so you should definitely put it in."

No, you have to use the standards compliant syntax for the type of, for creating and for calling member function pointers. VC++6 was more generous; eg when you wanted to create a function pointer you don't need to name the class it's in, unless ambiguous; that's simply not possible in standard C++.


The type of member function pointer to a function like

int Bar::Foo(int x);

is

int (Bar::*)(int)

and with a name (eg a variable or parameter of this type):

int (Bar::*function)(int)

To create a member function pointer you have to use the ampersand operator:

function = &Bar::Foo;

To call such a function you need the following syntax (assuming bar is a Bar* ):

(bar->*function)(42);

or (if bar is a Bar ):

(bar.*function)(42);

or (if bar is a smart pointer to Bar implementing operator* ):

((*bar).*function)(42);

Following may help:

class A
{
public:
    void foo();
};


int main(int argc, char* argv[])
{
    void (A::*mem_func)() = &A::foo;

    A a;

    (a.*mem_func)();

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM