【发布时间】:2024-04-27 03:50:02
【问题描述】:
例如,以下代码段使用 gcc-4.9 和 clang-602 编译
class Base
{
public:
static void foo() {}
void badfoo(int i) {}
};
template <typename T>
class Derived : public Base
{
public:
void bar() { Base::foo(); }
void badbar() { Base::badfoo(); } // compiles ok
//static void badbar() { Base::badfoo(); } // compile error
//void worsebar() { Base::nonexist(); } // compile error
};
int main()
{
return 0;
}
但是注释掉的行不会编译。
我的问题是:
为什么
badbar()编译但worsebar()不编译?如果我将
badbar()更改为静态,它也不会编译,无论base::badfoo是否为静态。标准是否说明在这种情况下应该检查什么? gcc4.4居然连
badbar()都拒绝编译。
更新:
许多答案已经解释了问题 1,但似乎编译器有时也会加倍努力检查过载,它发生在 gcc 4.4.3 和 4.8.2,但不是 4.7.2 和 4.9.1 .
问题 2:正如 Marco A. 指出的那样,clang 不会编译,但 gcc4.9 仍然可以通过。但是,gcc4.2 和 gcc4.4 都拒绝了代码,他们抱怨的错误是“没有匹配的函数”而不是“在没有对象的情况下调用非静态成员”。这个问题似乎没有确凿的答案,所以我按照 Daniel Frey 的建议添加了语言律师标签。
更多更新:
我认为问题 2 的答案现在很清楚:添加静态声明是否会改变诊断取决于编译器。它因编译器和同一编译器的不同版本而异。语言律师没有出现,我将接受 Daniel Frey 的回答,因为它最好地解释了第一个问题。但 Marco A. 和 Hadi Brais 的回答也值得一读。
【问题讨论】:
-
为什么会
worsebar编译?它试图调用一个不存在的函数。 -
@JoachimPileborg 但
Base::badfoo()也是一个不存在的函数。那为什么会编译呢? -
请编辑您的问题以显示您收到的实际错误,包括警告,完整和未编辑。
-
@juanchopanza 好的。 Joachims 的回答解释了除了
Base::badfoo();之外的所有内容,这确实很有趣,为什么它会编译。 -
对于静态函数,静态成员函数只能调用其他静态成员函数,没有明确的对象实例。
标签: c++ templates gcc clang language-lawyer