模板和非模板类的C++符号范围搜索顺序不同?

标签 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;
}

这给出了 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/

相关文章:

javascript - 带有模板和缓存的客户端 JS 框架?

java - for 循环中声明的变量范围

c++ - 为什么在比较 time_t 值时我的 While-Loop 不停止?

c++ - 类(class)的私有(private)成员在我的类(class)实例化期间发生了变化,即使他们不应该

c++ - 使用 operator new 从 C 实例化 C++ 对象

c++ - 构造函数的显式模板特化 (g++)

无法从当前范围之外的两个范围访问变量?

javascript - 为什么这个 Node.js 回调会起作用?

c++ - 用私有(private)基函数覆盖公共(public)虚函数?

c++ - 是否可以使用 decltype 来确定前向声明模板类的成员函数的返回类型?