C++如何知道模板类在编译时支持哪些方法

How does C++ know what methods a template class supports when compiling?

本文关键字:支持 方法 编译 何知道 C++      更新时间:2023-10-16
template <typename T>
void func(){
  T* t = new T();
  t->do_something();
  ...
}

在这种情况下,编译器如何知道类型名 T 将在其上定义do_something()方法?在Java中,我们可以指定泛型类扩展的接口,但C++显然没有相同的语法。那么如果我们打电话给func<AClassThatDoesntHaveDoSomethingDefined>()会发生什么?

编译器直到

您实例化模板函数才知道...与T.然后它会查找T是否有这样的方法......否则,您会收到错误。

将模板类型视为占位符,在模板函数实例化之前,不会为模板函数生成代码。因此,如果你有这样的函数并且它从未被调用过,尽管编译器仍然会对其进行一些语法一致性检查,但它不会成为程序集的一部分。这是模板的众多功能之一。

调用 func<AClassThatDoesntHaveDoSomethingDefined>() 时,编译器会将typename T替换为 AClassThatDoesntHaveDoSomethingDefined 。它将尝试创建如下函数:

void func(){
  AClassThatDoesntHaveDoSomethingDefined* t = new AClassThatDoesntHaveDoSomethingDefined();
  t->do_something();
  ...
}

通常的编译规则如下...如果未定义do_something(),则会收到错误。

这里有一些关于模板的更多信息:https://isocpp.org/wiki/faq/templates

模板在使用

之前不知道 nuthin。使用它们后,模板将转换为代码,并将模板参数替换为占位符。然后编译此生成的代码,如果这些替换参数中的任何一个不符合此新生成的代码的要求,则会收到错误消息。

分阶段思考。

定义以下模板

template<T>
bool func(T val)
{
    return val.getstate();
}

在编译过程中,

std::string test;
if (func(test))

找到并触发模板。然后编译器运行并创建

bool func(std::string val)
{
    return val.getstate();
}

从模板。一段时间后,在编译过程中,此生成的函数将被编译并发现std::string::getstate不存在,从而产生错误消息。