Google c ++风格如下。我不明白为什么前向声明会调用f(void *)。
可能很难确定是否需要前向声明或完整#include。用前向声明替换#include可以默默地改变代码的含义:
// b.h:
struct B {};
struct D : B {};
// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } // calls f(B*)
如果#include被替换为B和D的前向decls,test()将调用f(void *)。
答案 0 :(得分:5)
单独考虑这两个案例。通过将0
替换为标题的内容,我们首先得到:
null
有两种可能的重载。由于#include
继承自struct B {};
struct D : B {};
void f(B*) {}
void f(void*) {}
void test(D* x) { f(x); }
,因此D
可隐式转换为B
。在D*
和B*
之外,第一个是更好的匹配,因此选择了重载。但是,如果是前向声明的B*
和void*
:
B
D
无法从struct B;
struct D;
void f(B*) {}
void f(void*) {}
void test(D* x) { f(x); }
继承,因此无法从D
到B
进行隐式转换。唯一匹配的重载是D*
。