Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Visual Studio 2008在编译模板时不关心基类是否存在?_C++_Templates_Inheritance_C++11_Visual C++ 2008 - Fatal编程技术网

C++ Visual Studio 2008在编译模板时不关心基类是否存在?

C++ Visual Studio 2008在编译模板时不关心基类是否存在?,c++,templates,inheritance,c++11,visual-c++-2008,C++,Templates,Inheritance,C++11,Visual C++ 2008,VS2008处理类模板的继承方式似乎与其他编译器略有不同。 以下代码在VS 2008上编译时没有任何错误(使用默认选项): 模板 类someclass:公共不存在类 { T运算符()(S)常量{ 返回T(s); } }; 问题是,为什么?由于未定义的标识符不存在类,没有其他编译器能够做到这一点(尝试过GCC 4.5.0、英特尔、在线Comeau、VS 2005)。也许是新的C++0x标准中的某些东西证明了这种行为的合理性?Visual Studio的编译器从来没有因为其标准遵从性而出名。这肯定

VS2008处理类模板的继承方式似乎与其他编译器略有不同。 以下代码在VS 2008上编译时没有任何错误(使用默认选项):

模板
类someclass:公共不存在类
{
T运算符()(S)常量{
返回T(s);
}
};

问题是,为什么?由于未定义的标识符
不存在类
,没有其他编译器能够做到这一点(尝试过GCC 4.5.0、英特尔、在线Comeau、VS 2005)。也许是新的C++0x标准中的某些东西证明了这种行为的合理性?

Visual Studio的编译器从来没有因为其标准遵从性而出名。这肯定是另一个bug,万一你报告它,他们会告诉你他们有更重要的事情要做。不用说,一旦实例化该类,编译器就会发出错误


是的,有些东西在实例化之前编译器无法诊断。这不在它们的计数中,编译器必须发出诊断。当您说编译器接受该代码,而其他编译器不接受该代码时,C++0x不会更改此规则,您是指使用该代码还是同时实例化模板

模板在遇到定义时不编译,而是在实例化时编译。如果没有实例化模板,则可能是编译器完全忽略了整个模板定义(尽可能地忽略,因为它需要能够解释足够多的代码,以便知道模板定义何时完成)

然后在稍后的阶段,如果模板实际被实例化,并且假设模板没有专门化,编译器会抱怨。请注意,如果为特定类型提供专门化,则该专门化不需要从同一个不存在的类继承


在这种特殊情况下,我倾向于认为这是由于Microsoft编译器对依赖名称的特殊处理(如非标准处理)。与不需要在模板内的依赖名称前面指定
typename
的方式相同(考虑基类,或者使用此模板的type参数实例化不同的模板),编译器可能会考虑在实际实例化发生之前定义基类,然后等待那一刻执行验证。

这很可能是由于visual studio执行单阶段名称查找,而它应该执行两阶段名称查找。非依赖名称“non_existence_class”应该在第一阶段失败,无论模板是否实例化,都会在定义时失败

这是一个bug,但它永远不会被修复,直到微软从根本上改变了他们的编译器使用wrt模板的方式


VS2005拒绝编译这篇文章。必须是一些新功能,以加快编译模板繁重的代码。仅此代码。它在实例化时将失败。实际上,关于验证,您是绝对正确的,基类定义在哪里并不重要。也许这与C++0x的“外部模板”特性有关?不完全正确。在第一次传递中,仅允许保留未解析的从属名称。此示例不合格。@Surovov Victor:
extern模板
不是即将推出的标准的一部分(它在当前标准中,但仅由一个编译器制造商实现,而该供应商促进了从标准中删除)。David R。你错了。导出模板在标准中,将被删除,因为只有一个编译器实现了它,外部模板是C++0x的一个新特性,用于防止编译器在编译时实例化模板encountered@Crazy该标准允许编译器接受任何和所有模板定义——在解析/词法分析模板时,他们不必为非依赖名称提供错误。只有在实例化时,才需要进行诊断。如果在这一点之前提供了诊断,这就是实现的质量。
template <typename S, typename T>
class someclass : public non_existent_class
{
T operator() (S s) const {
    return T(s);
}
};