2016-04-04 22 views
3
template <typename T> 
void func(){ 
    T* t = new T(); 
    t->do_something(); 
    ... 
} 

在这种情况下,编译器如何知道typename T会在其上定义一个方法do_something()?在Java中,我们可以指定泛型类扩展的接口,但C++显然不具有相同的语法。那么如果我们拨打func<AClassThatDoesntHaveDoSomethingDefined>()会发生什么?C++如何知道模板类在编译时支持哪些方法?

+0

可能的重复:http://stackoverflow.com/q/122316/365102,http://stackoverflow.com/a/15671344/365102 –

+0

@MateenUlhaq号我不问如何在模板上添加约束。我更好奇为什么C++允许这样的代码编译,以及在未定义被调用的函数时如何处理这种情况。 – OneZero

+1

@OneZero语言的规则是,除非实例化模板,否则很少进行检查。然而,一旦模板被实例化 - 有足够的信息知道存在问题,不是? –

回答

7

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

想象模板类型(如占位符),没有为模板函数生成的代码,直到它使用类型实例化为止。所以如果你有这样的功能,而且它从来没有被调用过,那么它将不会是程序集的一部分。这是templates的许多功能之一。

当您致电func<AClassThatDoesntHaveDoSomethingDefined>()时,编译器用AClassThatDoesntHaveDoSomethingDefined代替typename T。编译如下

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

通常的规则...如果没有定义do_something(),你会得到一个错误:它会尝试创建这样的函数。

有上模板这里多一点信息:https://isocpp.org/wiki/faq/templates

+0

@CaptainGiraffe ...谢谢。回答修改...我希望现在更好;-) – WhiZTiM

1

模板不知道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不存在,从而产生错误消息。

相关问题