【问题标题】:How does C++ know what methods a template class supports when compiling?C++如何知道模板类在编译时支持哪些方法?
【发布时间】:2016-04-04 19:09:49
【问题描述】:
template <typename T>
void func(){
  T* t = new T();
  t->do_something();
  ...
}

在这种情况下,编译器如何知道 typename T 将定义一个方法 do_something() 呢?在 Java 中,我们可以指定泛型类扩展什么接口,但 C++ 显然没有相同的语法。那么如果我们调用func&lt;AClassThatDoesntHaveDoSomethingDefined&gt;()会发生什么呢?

【问题讨论】:

  • @MateenUlhaq 不。我不是在问如何在模板上添加约束。我更好奇为什么 C++ 允许编译这样的代码,以及它如何处理未定义被调用函数的情况。
  • @OneZero 该语言的规则是,在模板实例化之前,很少进行检查。但是,一旦模板被实例化 - 有足够的信息可以知道存在问题,不是吗?
  • 嗯,扩展一个类(在 Java 中)更像是派生自一个 C++ 中的类。它与模板无关。

标签: c++ templates generics


【解决方案1】:

直到你用T 实例化模板函数,编译器才知道。 然后它会查找T是否有这样的方法......如果没有,你会得到一个错误。

想想像占位符这样的模板类型,没有为模板函数生成代码,直到它被一个类型实例化。因此,如果您有这样的功能并且它从未被调用过,though it will still undergo some syntax conformance checks by the compiler,它就不会成为程序集的一部分。这是templates 的众多功能之一。

当您调用func&lt;AClassThatDoesntHaveDoSomethingDefined&gt;() 时,编译器会将typename T 替换为AClassThatDoesntHaveDoSomethingDefined。它会尝试创建这样的函数:

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

通常的编译规则如下...如果do_something()没有定义,你会得到一个错误。

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

【讨论】:

  • @CaptainGiraffe...谢谢。答案已修改...我希望现在更好;-)
【解决方案2】:

在使用模板之前,它们一无所知。一旦使用它们,模板就会变成代码,其中模板参数替换占位符。然后编译这个生成的代码,如果这些替换的参数中的任何一个不符合这个新生成的代码的要求,那么你会收到一条错误消息。

分阶段考虑。

您定义以下模板

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 不存在,产生错误消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 2015-11-24
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    相关资源
    最近更新 更多