首页 > 编程语言 >C++ 模板类编译过程中出现“undefined reference to”问题

C++ 模板类编译过程中出现“undefined reference to”问题

时间:2023-06-14 10:48:01浏览次数:42  
标签:undefined reference 编译 C++ queue _. template 模板 函数

问题描述

C++在使用模板(template)类的时候,如果将类的成员函数的声明和实现分别放在.h头文件和.cpp源文件中,编译时会报错undefined reference xxx,找不到对应成员函数。

起因

.h文件中类的声明为:

// 线程池,定义成模板类,为了代码的复用
template <typename T>
class ThreadPool {
    ...
  public:
    bool append(T *request);
    ...
};

.cpp文件中成员函数的实现为:

template <typename T>
bool ThreadPool<T>::append(T *request) {
    // 操作工作队列时一定要加锁,因为它被所有线程共享
    queue_locker_.lock();
    if (work_queue_.size() > max_requests_) {
        queue_locker_.unlock();
        return false;
    }

    work_queue_.push_back(request);
    queue_locker_.unlock();
    queue_sta_.post();
    return true;
}

直接使用g++编译,会报错: atMelNiX1Zn3EKj

原因分析

template其实是一种类似语法糖的东西,C++中每一个对象所占用的空间大小,是在编译的时候就确定的,在模板类没有真正的被使用之前,编译器是无法知道,模板类中使用模板类型的对象的所占用的空间的大小的。只有模板被真正使用的时候,编译器才知道,模板套用的是什么类型,应该分配多少空间。这也就是模板类为什么只是称之为模板,而不是泛型的缘故。

ThreadPool<int>Thread<HttpConn>是两个不同的类型,其成员函数也是两个不同的成员函数。

在编译thread_pool.cpp时,编译器会去查找对类Thread<HttpConn>的声明,如果找不到这个声明,那么就报错了。

解决方案

在成员函数的实现的代码所在的源文件的开头,声明该类,即添加:

template class ThreadPool<HttpConn>;

或者将函数的实现也写在头文件中(不推荐)。

标签:undefined,reference,编译,C++,queue,_.,template,模板,函数
From: https://www.cnblogs.com/zwyyy456/p/17479524.html

相关文章

  • C/C++《程序设计课程设计》[2023-06-14]
    C/C++《程序设计课程设计》[2023-06-14]《程序设计课程设计》指导书程序设计课程设计说明书一、设计任务与要求《程序设计课程设计》是在完成《程序设计基础》课程学习后进行的一门专业实践课程,是培养学生综合运用所学知识解决专业相关问题的重要环节,是对学生实际工作能力的......
  • 配置 Sublime Text4为 C++ 编辑器
    概述涉及以下插件的安装和配置PackageControlTerminusLSPLSP-clangdclang-formatLSP-pyrightLSP-json配置sublime安装PackageControl以进行包管理。Terminus安装Terminus以实现sublimetext4内的terminal。绑定快捷键:[ { "keys":[ "ctrl+shift+t" ], "c......
  • C++面试八股文:C++中,函数的参数应该传值还是传引用?
    C++面试八股文:C++中,函数的参数应该传值还是传引用?某日二师兄参加XXX科技公司的C++工程师开发岗位第8面:面试官:C++中,函数的参数应该传值还是传引用?二师兄:要看参数的用途。如果是出参,必须传引用。如果是入参,主要考虑参数类型的大小,来决定传值还是传引用。面试官:为什么不使用......
  • C++面试八股文:什么是RAII?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第13面:面试官:什么是RAII?二师兄:RAII是ResourceAcquisitionIsInitialization的缩写。翻译成中文是资源获取即初始化。面试官:RAII有什么特点和优势?二师兄:主要的特点是,在对象初始化时获取资源,在对象析构时释放资源。这种技术可以......
  • C++面试八股文:什么是RAII?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第13面:面试官:什么是RAII?二师兄:RAII是ResourceAcquisitionIsInitialization的缩写。翻译成中文是资源获取即初始化。面试官:RAII有什么特点和优势?二师兄:主要的特点是,在对象初始化时获取资源,在对象析构时释放资源。这种技术可以......
  • 《C++》类和对象
    C++面向对象的三大特性:封装、继承、多态封装将属性和行为作为一个整体,表现生活中的事物。对属性和行为加以权限控制。classCompute{ //访问权限public: intAdd(intx,inty) { returnx+y; } intSub(intx,inty) { returnx+y; } intMul(intx,inty) {......
  • 现代C++学习指南-方向篇
    C++是一门有着四十年历史的语言,先后经历过四次版本大升级(诞生、98、11、17(20),14算小升级)。每次升级都是很多问题和解决方案的取舍。了解这些历史,能更好地帮助我们理清语言的发展脉络。所以接下来我将借它的发展历程,谈一谈我对它的理解,最后给出我认为比较合理的学习路线指南。C++0......
  • 论c++实现sql连接
    寻找关于c++对sql连接的过程非常艰辛。今天要做一个简单项目,要求在远程sql上实现对数据的实时模拟,每五分钟进行一次随机产生数据并写入。在此之前我并没有用过代码实现sql连接的经历,在翻阅无数资料后,终于实现了使用visualstudio对mysql的连接。第一步,添加mysql的依赖文件,在v......
  • 《C++》函数重载
    函数默认值函数调用时传入数据则覆盖默认值,反则使用默认值intAdd(inta,intb=0,intc=0){ returna+b+c;}intmain(){ intret=Add(1,3); cout<<ret<<endl; system("pause"); return0;}如果从一个位置设置默认参数,其后也必须设置默认参数若函数声明有默认......
  • 现代C++学习指南-类型系统
    在前一篇,我们提供了一个方向性的指南,但是学什么,怎么学却没有详细展开。本篇将在前文的基础上,着重介绍下怎样学习C++的类型系统。写在前面在进入类型系统之前,我们应该先达成一项共识——尽可能使用C++的现代语法。众所周知,出于兼容性的考虑,C++中很多语法都是合法的。但是随着新......