转发声明vs包含在谷歌c++;风格指南 谷歌C++风格有以下几点:我不明白为什么转发声明会调用f(void*)

转发声明vs包含在谷歌c++;风格指南 谷歌C++风格有以下几点:我不明白为什么转发声明会调用f(void*),c++,include,forward-declaration,C++,Include,Forward Declaration,很难确定是否需要提前声明或完全包含。用转发声明替换#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*) 如果将B和D的#include替换为forward decls,test()将调用f(voi

很难确定是否需要提前声明或完全包含。用转发声明替换#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*)

如果将B和D的#include替换为forward decls,test()将调用f(void*)。

分别考虑这两种情况。通过用标题的内容替换
#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*
隐式转换为
B*
。唯一匹配的重载是
f(void*)

如果您只执行
struct D则继承未知。