C++模板——待决名

发布时间 2023-10-09 16:15:47作者: 3的4次方

C++模板——待决名

本文将持续更新,如果有了解这块内容的小伙伴欢迎评论区留言,最近遇到这个问题很多次了?

概念

参考官方文档:

简单来说:

template<typename T>
struct X {
    void f_x(){}
};
template<typename T>
struct Y : X<T> {
    void f_y() {
        f_x(); // 非待决名,函数查找在不知道T的具体类型时就查找【立即绑定】
        this->f_x(); // 待决名,函数查找在知道T的具体类型时才查找【待会绑定】
    }
}

在模板中的使用

参考官方文档:无限定的名字查找 - cppreference.com

问题

问题1:

#include <iostream>

template<typename T = int>
class Base {
public:
    Base() :m_a(0) {}
    Base(T a) :m_a(a) {}
    virtual void func(){
        // 假设T类型重载了<<运算符且能被输出
        std::cout << "Base func()" << m_a << std::endl;
    }
protected:
    T m_a;
};

template<typename T = int>
class Derived :public Base<T> {
public:
    Derived() : Base<T>() {}
    Derived(T a, T b) :Base<T>(a), m_b(b) {}
    void func() override {
        // 假设T类型重载了<<运算符且能被输出
        std::cout << "Derived func()" << m_a << " " << m_b << std::endl;
    }
private:
    T m_b;
};

int main() {
    Derived o(2.3, 1.4);
    o.func();
    return 0;
}

上述代码中,这句std::cout << "Derived func()" << m_a << " " << m_b << std::endl;报错:m_a未声明的标识符。

而如果将使用m_a改为this->m_a,或者在继承模板类时将模板类实例化为特定的类型,比如Base<int>,就不会报错了。

问题2:

// 将邻接表转为邻接矩阵
template <typename T = char>
void convertToMartix(ALGraph<T>& g, MGraph<T>& m) {
    for (int i = 0; i < g.vex_num; i++) {
        auto p = g.node[i].first; // first是非待决名的,解决方法同问题1
        while (p != nullptr) {
            m[i][p->adjvex] = 1;
            p = p->next;
        }
    }
}