#include <iostream>
void foo()
{
std::cout << "global foo()" << std::endl;
}
struct A {
void foo()
{
std::cout << "A::foo()" << std::endl;
}
};
struct B : public A {
void call()
{
foo();
}
};
int main(int argc, char **argv )
{
B b;
b.call();
return 0;
}
这给出了 expected result :
A::foo()
但是在更改两行之后(B 类到模板):
#include <iostream>
void foo()
{
std::cout << "global foo()" << std::endl;
}
struct A {
void foo()
{
std::cout << "A::foo()" << std::endl;
}
};
template <typename T> // change here
struct B : public T {
void call()
{
foo();
}
};
int main(int argc, char **argv )
{
B<A> b; // and here
b.call();
return 0;
}
我得到 unexpected result :
global foo()
并且使用 this->
不是一种选择,因为我正在尝试创建“后备”机制。
最佳答案
你得到的是预期的结果。这在 C++ 标准中称为“两阶段名称查找”。
模板内的名称分为两种:
Dependent – 依赖于模板参数但不在模板中声明的名称。
不依赖 – 不依赖于模板参数的名称,加上模板本身的名称和在其中声明的名称。
当编译器试图解析代码中的某个名称时,它首先判断该名称是否依赖,而解析过程源于这种区别。虽然“正常”解析非依赖名称 - 当定义模板时,依赖名称的解析发生在模板实例化的点。
foo();
在您的示例中 B::call
是一个非依赖名称,因此它被解析为全局 foo()
在模板定义处。
关于模板和非模板类的C++符号范围搜索顺序不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10248396/