elm*_*lmo 16 c++ templates scope
#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;
}
Run Code Online (Sandbox Code Playgroud)
这给出了预期的结果:
A::foo()
Run Code Online (Sandbox Code Playgroud)
但是在更改了两行之后(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;
}
Run Code Online (Sandbox Code Playgroud)
我得到了意外的结果:
global foo()
Run Code Online (Sandbox Code Playgroud)
并且使用this->不是一个选项,因为我正在尝试创建一个"后备"机制.
And*_*rey 16
你得到的是预期的结果.这在C++标准中称为"两阶段名称查找".
模板内的名称分为两种类型:
从属 - 依赖于模板参数但未在模板中声明的名称.
非依赖 - 不依赖于模板参数的名称,加上模板本身的名称和在其中声明的名称.
当编译器尝试解析代码中的某个名称时,它首先决定名称是否依赖,并且解析过程源于此区别.虽然非依赖名称是"正常"解析的 - 当定义模板时,依赖名称的解析发生在模板实例化的时刻.
foo();在B::call您的示例中,in是一个非依赖名称,因此foo()在模板定义时将其解析为全局.