两阶段查找-需要说明


Answers:


67

模板被编译(至少)两次:

  1. 如果没有实例化,则将检查模板代码本身的语法。
    例如:任何语法错误,例如;etc。

  2. 在实例化时(确切类型已知时),将再次检查模板代码以确保所有调用对该特定类型均有效。
    例如:模板可能会依次调用该特定类型可能不存在的函数。

这称为两阶段查找。


49
还要注意,在第一阶段完成对非依赖名称的查找,而在第二阶段完成对依赖模板参数的名称的查找。重要性在于,如果调用sqrt(1),则sqrt需要在定义模板之前先进行声明。但是,如果您调用sqrt(t),其中t是类型实例是模板参数,那么sqrt在实例化模板之前就不需要看到它。MSVC过去并不能正确地做到这一点:据我所知,可能还不是。
史蒂夫·杰索普

14
无论如何,这就是为什么它被称为两阶段查找而不是仅两阶段编译之类的原因。第一阶段是应该做的更多,而不仅仅是语法检查,但MS不得不实施第一阶段查找一些困难,所以他们只是做了它所有的实例:stackoverflow.com/questions/6273176/...
史蒂夫·杰索普

3
历史评论:我使用的编译器具有大括号计数阶段和编译阶段,template <class T> class C { put really anything here & ~ - (but nothing unbalanced and no 8-bit char outside string literal) }如果C从未实例化,那么给出的IOW将被接受!那是十多年前的事了。
curiousguy 2011年

2
出于好奇,本文摘录自《C ++模板:完整指南》
legends2k 2014年

2
除了@SteveJessop对从属名称的注释之外,还值得指出的是,在从属名称上发生的是“自变量依存查找”。这意味着::sqrt(::NS::A)将不会找到,因为将在中::NS而不在中进行其他查找::。最后一点是,不会搜索别名的范围,即typedef或using的范围,仅搜索alised类型本身的范围。
理查德·科登
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.