通过引用传递时,类模板是否被实例化?

m79*_*13d 5 c++ templates class-template

考虑以下示例:

template <typename T>
class A
{
public:
  void foo () const {t->foo();}
  virtual void fooVirtual() {t->foo();} // MSVC: use of undefined type 'B'
  
protected:
  T* t;
};

class B; // only forward declared

const A<B>& get(); // will be defined in another translation unit
void foo(const A<B>& a); // will be defined in another translation unit

int main () 
{
  const A<B>& a = get();
  foo(a); // MSVC: class template instantiation 'A<B>' being compiled
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这会在 CLang 和 GCC 中编译,但会生成上面由 MSVC 提到的错误消息。哪种编译器行为符合 C++ 标准?

A<B>当通过引用传递时,是否应该实例化类模板特化 ( )?

请参阅编译器资源管理器中的示例

n. *_* m. 5

[ temp.inst ] “...当在需要完全定义的对象类型的上下文中引用专门化时,或者当类类型的完整性影响程序的语义时,类模板专门化会被隐式实例化。”

我认为这里的情况并非如此。让我们用不完整的类型替换专业化:

class A;
void foo(const A& a);

const A& get();

int main () 
{
  const A& a = get();
  foo(a);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这编译得很好(演示),所以此时不​​需要完整的类型。添加一对花括号后class A什么都不改变。所以 MSVC 可能是错误的。