6

可能重复:
如何指定指向重载函数的指针?

我有一个库,其类定义为:

struct ClassA
{
    static ClassA foo(long);
    static ClassA foo(double);
}

我需要获取这两个函数的地址。我目前正在尝试的代码给出错误 C2440: cannot convert from 'overloaded-function' to '...'

ns::ClassA (ns::ClassA::*ClassA_foo1)(long) = &ns::ClassA::foo;
ns::ClassA (ns::ClassA::*ClassA_foo2)(double) = &ns::ClassA::foo;

我认为这可能是因为它们是静态的,但是在返回类型之前或之后放置静态会产生相同的错误。

4

3 回答 3

5

函数重载的事实并不真正相关。这里真正的问题是函数指针和成员函数指针之间的区别。我将在不重载的情况下运行一些示例。

解决方案:要么删除static, 以便将它们定义为成员函数。否则替换ns::ClassA::*ClassA_foo1*ClassA_foo1. 我想你想要后者。(但我实际上建议您使用typedef,正如其他人已经建议的那样)。

考虑这两个:

namespace ns {
struct ClassA
{
    static ClassA foo(long);
};
}

namespace ns {
struct ClassA
{
    ClassA foo(long);
};
}

在前一种情况下, foo 是static并且因此是一个典型的函数,并且可以存储在函数指针中:

ns::ClassA (ClassA_foo1)(long) = &ns::ClassA::foo;

如果删除static,则它不再是函数,而是成员函数。指向成员函数的指针与指向函数的指针不同,它们必须使用一个对象来执行,该对象将this是调用该方法的对象。

函数指针的类型包括返回值的类型和参数的类型。但是指向成员函数的指针的类型还必须包括this对象的类型——您不会期望能够从 aCircle类型的对象上运行方法BankAccount

声明一个指向函数的指针:

 ReturnType (*variable_name) (PARAM1, PARAM2)

声明一个指向成员函数的指针:

 ReturnType (ThisObjectType::*variable_name) (PARAM1, PARAM2)

最后一行很有趣。乍一看,您可能会认为它R (A::*v) (P1,P2)声明了一个普通的函数指针并将结果变量v放入A作用域。但事实并非如此。相反,它定义了一个指向成员函数的指针,该函数对类型的对象进行操作A

于 2012-08-31T18:55:47.350 回答
4

The problem that you are observing has absolutely nothing to do with the fact that the function is overloaded. You'd get the same error for a non-overloaded function.

Static member functions have ordinary function type. Meanwhile, you are trying to interpret them as functions of member-function type. This leads to pointer type mismatch reported to you by the compiler. Here's a simple example that will fail to compile for the very same reason

struct S {
  static void foo();
};
...
void (S::*p)() = &S::foo; // ERROR, pointer type mismatch

In other words, your pointers are declared as pointers of pointer-to-member-function type. Such pointers cannot hold the address of a static member function. A static member function and a non-static member function are beasts of completely different nature. The corresponding pointer types are not compatible and not convertible to each other. That's the reason for your error.

This is how it was probably supposed to look

ns::ClassA (*ClassA_foo1)(long) = &ns::ClassA::foo;
ns::ClassA (*ClassA_foo2)(double) = &ns::ClassA::foo;

i.e. the pointers on the left-hand side should be declared as ordinary function pointers, not as member function pointers.

于 2012-08-31T19:05:13.640 回答
0
ns::ClassA (ns::ClassA::*ClassA_foo1)(long) = &ns::ClassA::foo;
ns::ClassA (ns::ClassA::*ClassA_foo2)(double) = &ns::ClassA::foo;

看起来您正在尝试在文件范围内ClassA_foo1设置这对静态成员。ClassA_foo2如果是这样,这不是有效的语法。定义静态成员的语法是

SomeType ClassName::member = initializer;

最好使用 typedef 来声明和定义ClassA_foo1and ClassA_foo2

struct ClassA {
   typedef ClassA (*ClassALongGenerator) (long);
   typedef ClassA (*ClassADoubleGenerator) (double);

   static ClassALongGenerator ClassA_foo1;
   static ClassADoubleGenerator ClassA_foo2;
};

然后在某个源文件的文件范围内

ns::ClassALongGenerator ClassA_foo1 = ns::ClassA::foo;
ns::ClassADoubleGenerator ClassA_foo2 = ns::ClassA::foo;
于 2012-08-31T18:29:58.833 回答