C++模板——待决名

C++模板------待决名

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

概念

参考官方文档:

简单来说:

cpp 复制代码
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:

cpp 复制代码
#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; // m_a是非待决名
    }
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未声明的标识符。

解决方案

  • 法1,让成员成为待决名的:将使用m_a改为this->m_a,或使用显式指定m_a命名空间为Base<T>::m_a
  • 法2,保留成员为非待决名不动,让模板类实例化:在继承模板类时将模板类实例化为特定的类型,比如Base<int>,就不会报错了

问题2:

cpp 复制代码
// 邻接矩阵
template <typename T = char>
struct MGraph {
    T vex[MAX_VERTEX_NUM];                     // 顶点表(用来存放顶点的信息)
    int edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  // 邻接矩阵(用来存放边和边权)
    int vex_num, arc_num;                      // 当前的顶点数和弧数
};

// 邻接表
struct ArcNode {  // 边表结点
    int adjvex;   // 出边终点在顶点表中的下标
    ArcNode* next;
};
template <typename T = char>
struct VNode {  // 顶点表结点
    T data;
    ArcNode* first;
};
template <typename T = char>
struct ALGraph {                    // 邻接表类型
    VNode<T> node[MAX_VERTEX_NUM];  // 顶点表,其中的每个顶点都连着一个出边表
    int vex_num, arc_num;           // 当前的顶点数和弧数
};

// 将邻接表转为邻接矩阵
template <typename T = char>
void convertToMatrix(ALGraph<T>& g, MGraph<T>& m) {
    for (int i = 0; i < g.vex_num; i++) {
        auto p = g.node[i].first;  // first是非待决名。不过这里编译能通过,只不过这里写auto的话用不了代码提示了
        while (p != nullptr) {
            m.edge[i][p->adjvex] = 1;
            p = p->next;
        }
    }
}

解决方案

  • 法1,让first成为待决名的,即用typename关键字显式指定p的类型:typename Graph::ArcNode* p = g.node[i].first;
  • 法2,保留成员为非待决名不动,让模板函数实例化
相关推荐
给大佬递杯卡布奇诺16 分钟前
FFmpeg 基本数据结构 AVInputFormat 分析
数据结构·c++·ffmpeg·音视频
Evand J19 分钟前
【自适应粒子滤波MATLAB例程】Sage Husa自适应粒子滤波,用于克服初始Q和R不准确的问题,一维非线性滤波。附下载链接
开发语言·matlab·卡尔曼滤波·自适应滤波·非线性
给大佬递杯卡布奇诺20 分钟前
FFmpeg 基本数据结构 AVCodecContext分析
数据结构·c++·ffmpeg·音视频
roykingw22 分钟前
【思想比实现更重要】高并发场景下如何保证接口幂等性
java·web安全·面试
hd51cc44 分钟前
C++ 类的学习(四) 继承
开发语言·c++·学习
紫荆鱼1 小时前
设计模式-命令模式(Command)
c++·后端·设计模式·命令模式
864记忆1 小时前
Spring Boot 项目标准目录结构
java
编码追梦人1 小时前
深耕 Rust:核心技术解析、生态实践与高性能开发指南
开发语言·后端·rust
2301_772093561 小时前
KVSTORE_Pain point_tuchuang_ROS2
java·开发语言·1024程序员节
刘火锅1 小时前
Java 17 环境下 EasyPoi 反射访问异常分析与解决方案(ExcelImportUtil.importExcelMore)
java·开发语言·python