以void *和其他指针类型为参数的C++多态函数: is it considered ambiguous?

标签 c++ overloading implicit-conversion void-pointers pointer-conversion

void * 和其他指针类型作为参数的 C++ 多态函数:它是否被认为是有歧义的?

我担心,因为任何指针都可以转换为 void*,下面的 bar 的第二次调用是否会执行 void bar(void*) 而不是我预期的 void bar(int*),在下面的程序中?

我在我的 g++ 上进行了测试,它按预期运行(即 int* 不会转换为 void*)。但是任何人都可以在 C++ 语言规范方面评论/回答这个问题吗?

foo.h:

class Foo {
public:
    void bar(void *);
    void bar(int *);
};

主要.cpp:

...
struct A *p1;
int *p2;
Foo foo;
...
foo.bar(p1);
foo.bar(p2);

此外,比方说,bar 现在是虚拟多态函数,以 void* 参数作为第一种形式,将基抽象类指针参数作为第二种形式。使用派生类指针作为参数的调用会执行第一种形式还是第二种形式?即派生类指针将被转换为它的基抽象类指针(因此第二种形式将起作用),还是将其转换为 void *(因此第一种形式将起作用) action) 在调用 bar() 之前?

最佳答案

根据 overload resolution rules (section Ranking of implicit conversion sequences) ,因为参数可以转换为任一函数的参数类型,所以在这种情况下最好的可行函数是隐式转换更好的函数。

对于:

class Foo {
  public:
    void bar(void*);
    void bar(int*);
};

// ...

Foo foo;
int* p2;
foo.bar(p2);

第一个是排名 3(转化),第二个是排名 1(完全匹配)。由于不需要转换的精确匹配优于转换,因此它将调用 void bar(int*)

然而,在你的第二种情况下它变得更加复杂:

class Foo {
  public:
    virtual void bar(void*);
    virtual void bar(Foo*);
    virtual ~Foo() = default;
};

class FooTwo : public Foo {};

// ...

Foo foo;
FooTwo footwo;

foo.bar(&footwo);

由于两者都是排名 3(转化),因此遵循转化排名规则。由于这两个转化具有相同的转化排名,因此这将适用于扩展的转化排名规则。扩展规则 2 规定:

Conversion that converts pointer-to-derived to pointer-to-base is better than the conversion of pointer-to-derived to pointer-to-void, and conversion of pointer-to-base to void is better than pointer-to-derived to void.

考虑到这一点,void bar(Foo*) 被认为是比 void bar(void*) 更好的匹配,这意味着它将被 foo 选择.bar(&footwo);.

参见 here以后者为例。

关于以void *和其他指针类型为参数的C++多态函数: is it considered ambiguous?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33690770/

相关文章:

javascript - AngularJS 将字符串转换为引用 $scope 中对象的对象/数组

java - 通过传递 0 和 null 为 Null 参数重载方法

c++ - 将 std 字符串访问器与 ostream 运算符 << 一起使用

c++ - 如何调用对象的析构函数,如果它的指针地址存储为无符号整数,这是唯一已知的东西?

c++ - automake Mingw 交叉编译链接到已安装静态库的共享库的问题

c++ - 具有两个 getInstance() 方法的单例移交父指针?

c - MISRA 违规 12.9 一元减号的操作数未签名

unsigned long 乘以 float 会变成负数吗?

c++ - 为什么 ubuntu 附带的内存分配器比 google tcmalloc 慢 2 倍?

c++ - vector 的lock_guards