2

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

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

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

4

3 回答 3

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

于 2011-03-04T20:22:31.453 回答
0

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

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

于 2011-03-04T19:12:07.107 回答
0

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

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

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

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

于 2011-03-04T19:54:54.263 回答