【问题标题】:Visual Studio 2008 does not care about base class existence when compiling templates?Visual Studio 2008 在编译模板时不关心基类的存在?
【发布时间】:2011-03-04 19:08:51
【问题描述】:

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

template <typename S, typename T>
class someclass : public non_existent_class
{
T operator() (S s) const {
    return T(s);
}
};

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

【问题讨论】:

    标签: c++ templates inheritance c++11 visual-c++-2008


    【解决方案1】:

    这很可能是由于 Visual Studio 在应该执行两阶段时执行单阶段名称查找这一事实的结果。非依赖名称“non_existent_class”应该在第一阶段失败,无论模板是否被实例化,都会发生在定义点。

    这是一个错误,但在 MS 从根本上改变他们的编译器对模板的工作方式之前,它永远不会被修复。

    http://womble.decadent.org.uk/c++/template-faq.html#two-phase

    http://blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html

    【讨论】:

      【解决方案2】:

      Visual Studio 的编译器从不以符合标准而闻名。这一定是另一个错误,如果你报告它,他们会告诉你他们有更重要的事情要做。不用说,一旦你实例化了这个类,编译器就会报错。

      是的,编译器在实例化之前无法诊断出某些事情。这不在他们的计数之内,编译器必须发出诊断。 C++0x 没有改变这个规则

      【讨论】:

      • VS 2005 拒绝编译这个。必须是一些新功能来加快模板繁重代码的编译速度。
      【解决方案3】:

      当您说编译器接受该代码而其他编译器不接受时,您是指使用那段代码还是实例化模板?

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

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

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

      【讨论】:

      • 只有这个代码。实例化时会失败。实际上,您对验证是绝对正确的,在哪里定义基类并不重要。可能和 C++0x 的“外部模板”特性有关?
      • 不完全正确。在第一遍中,只允许从属名称保持未解析。此示例不符合条件。
      • @Surovov Victor: extern template 不是即将发布的标准的一部分(它在当前标准中,但仅由一家编译器制造商实施,同一供应商推动从标准中删除)
      • David R. 你错了。 export 模板在标准中,将被删除,因为只有一个编译器实现了它,extern 模板是 C++0x 的一个新特性,用于防止编译器在遇到时实例化模板
      • @Crazy 标准允许编译器接受任何和所有模板定义——在解析/分析模板时,即使是非依赖名称也不必给出错误。只有在实例化时,才需要进行诊断。如果在此之前提供了诊断,则说明实施质量良好。
      猜你喜欢
      • 1970-01-01
      • 2012-09-24
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 2013-07-26
      • 2015-07-11
      • 1970-01-01
      相关资源
      最近更新 更多