问题描述
Visual Studio 不会因为每个函数前的模板行而给我错误.
Visual studio isn't giving me errors because of the template line before each function.
例如:
template <class keyType, class valueType>
void Map<keyType, valueType>::remove (keyType key)
{
cout<<"hello"
}
它不会因为 cout 上缺少分号而给我一个错误.
It won't give me an error for the missing semicolon on the cout.
我该如何解决这个问题?谢谢!
How can i fix this? Thanks!
推荐答案
这是 Visual C++ 编译器的一个众所周知的弱点.归结为:模板主体不会被解析,除非模板被实例化.
This is a well-known foible of the Visual C++ compiler. It boils down to this: Template bodies are not parsed unless and until the template is instantiated.
当编译器找到模板定义时,它会将其复制到内部缓冲区中以备将来参考.然后,当使用具体类型实例化该模板时,它会执行搜索和替换以放入具体类型,然后解析模板.
When the compiler finds a template definition, it copies it into an internal buffer for future reference. Then, when that template is instantiated with concrete types, it does a search-and-replace to put the concrete types in and then parses the template.
这有几个不好的影响:
- 如您所见,未实例化的模板不会提供错误消息.这意味着您可以编写垃圾代码,将其保留在代码库中并且没有问题,直到数年后有人愚蠢地实例化您的模板并且构建以可怕的方式中断.
- 因为编译器在解析模板时知道模板参数,所以依赖名称和非依赖名称之间的区别就消失了.
- 同样,模板的解析上下文是实例化上下文,而不是定义上下文.所以,如果你在模板中引用了一个自由函数,你最好希望函数名在代码的不同部分没有不同的定义......
- 因为编译器在解析模板时知道模板参数,所以当标准说它不应该并且你应该使用
typename
关键字来告诉它区别.此类代码不会在任何其他编译器下编译.
- As you've noted, uninstantiated templates don't give error messages. This means you can write crap code, leave it in the code base and have no problem until, years down the line, someone foolishly instantiates your template and the build breaks in horrible ways.
- Because the compiler knows the template parameters when it parses the template, the distinction between dependent and non-dependent names disappears.
- Similarly, the parsing context for the template is the instantiation context, not the definition context. So, if you refer to a free function in your template, you'd better hope that function name doesn't have different definitions in different parts of your code...
- Because the compiler knows the template parameters when it parses the template, there are many places where VC++ can tell the difference between a type name and an expression when the standard says it shouldn't and you should have to use the
typename
keyword to tell it the difference. Such code won't compile under any other compiler.
很公平,从前所有编译器都以这种方式解析模板.其他人都看到了它的可维护性和可移植性灾难,但微软没有.是时候继续前进了.
Fair enough, once upon a time all compilers parsed templates this way. Everyone else has seen it for the maintainability and portability disaster that it is, but not Microsoft. Time to move on.
这篇关于由于每个函数之前的模板,Visual Studio 没有给我错误.C++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!