首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用模板时,C++没有匹配调用的函数,链接器错误

在使用模板时,C++出现没有匹配调用的函数,链接器错误的问题通常是由于模板的实例化问题引起的。当编译器在链接阶段无法找到模板函数的实例化版本时,就会出现这个错误。

解决这个问题的方法有以下几种:

  1. 确保模板函数的定义和声明都在可见范围内:在使用模板函数之前,需要确保模板函数的定义或声明已经在当前的源文件或头文件中可见。可以通过将模板函数的定义和声明放在同一个文件中,或者使用头文件包含的方式来实现。
  2. 显式实例化模板函数:如果模板函数的实例化版本在编译期间无法自动推导出来,可以使用显式实例化的方式来告诉编译器生成特定类型的实例化版本。例如,对于一个模板函数template <typename T> void foo(T value),可以在源文件中使用template void foo<int>(int value);来显式实例化一个int类型的版本。
  3. 提供模板函数的定义:如果模板函数只有声明而没有定义,链接器就无法找到实例化版本。因此,需要确保模板函数的定义在可见范围内,可以将模板函数的定义放在头文件中,或者在使用模板函数的源文件中提供定义。
  4. 检查模板函数的参数类型:链接器错误也可能是由于模板函数的参数类型不匹配导致的。请确保调用模板函数时传入的参数类型与模板函数的参数类型一致或可以隐式转换。

总结起来,解决C++模板函数没有匹配调用的问题,可以通过确保模板函数的定义和声明可见、显式实例化模板函数、提供模板函数的定义以及检查参数类型等方法来解决。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++模板进阶

,若不匹配,则编译会报一些奇怪错误。...部分特化后模板属于办成品,如果在传参,某一个参数是属于部分特化后参数,则编译优先调用那个部分特化模板。...下面的main函数用于验证编译对于模板优先匹配机制,编译总是会优先调用现成模板,实在没有的时候,编译才会自己推演实例化。...在使用模板显示实例化地方,只有.h文件展开,而没有.cpp文件,因为在链接之前,各源文件之间是互不联系,所以即使你显示实例化了类模板,但在类模板真正定义地方却没有实例化,所以在链接时候.cpp...里面没有实例化出来模板,自然链接就会出问题,因为你用了一个并没有真正实例化出来类,编译就会报链接错误

1K20

函数申明对函数模板实例化屏蔽

1.C++函数匹配顺序 C++语言引入模板机制后,函数调用情形显比C语言要复杂。当发生一次函数调用时,如果存在多个同名函数,则C++编译将按照如下顺序寻找对应函数定义。...(1)寻找一个参数完全匹配函数,如果找到了就调用它。 (2)寻找一个函数模板,并根据调用情况进行参数推演,如果推演成功则将其实例化,并调用相应模板函数。...函数申明对函数模板实例化屏蔽 如果使用函数申明,可能会造成对函数模板实例化屏蔽。考察如下程序。...但是由于前面那个函数申明存在,使得编译认为一定有一个int square(const int&)存在,不启用函数模板实例化,并尝试寻找该函数定义,结果该函数没有定义,就出现了连接未找到该函数定义错误...这种现象,可以把它叫做函数申明对函数模板实例化屏蔽。其本质是,在发生函数调用时候,编译总是优先调用普通函数而不是函数模板。要解决这个问题,可以采取以下三种办法。 (1)去掉函数申明。

60320

C++打怪升级(八)- 泛型编程初见

,否则会报错 所以编译原则是在最满足匹配,优先调用显式实现; ---- 类模板 接下来介绍类模板; 相比函数模板,类模板使用更加广泛 引子 类模板出现是为了解决一些问题,与函数模板相似...编译对于类模板类型一般没有推导时机,而是需要我们对类模板显式实例化 类模板函数定义在类模板相比普通函数需要更多处理: 完整地类名是类模板名+; 指定类外函数作用域也要使用完整类名...原因分析 类模板分离编译会报链接错误 一般建议类模板在同一个文件中声明和定义分离,这是最好方式了,达到了类中简洁只有函数声明,同时没有各种错误; 来看看类声明和定义分离且不在一个文件会遇到问题...: 程序运行报错 - 链接错误 test.o文件找不到要调用由类模板实例化成员函数,那么为什么找不到呢?...这牵扯到了多个源文件编译链接过程 链接错误,说明不是语法问题,而是链接,test.o在class.o中找不到要调用模板实例化出来函数,即类模板没有实例化处具体函数,class.o符号表中也就没有相应函数地址

79520

模板进阶:特化与编译链接全解析

参数一致性:特化函数参数列表必须与原模板函数保持一致,不能增加或减少参数,也不能更改参数顺序或类型。 **注意:**推荐直接写一个函数实现特殊处理,编译在处理时候会优先调用匹配。...偏特化:允许对部分模板参数进行特化,同时保持其他参数泛型性。在实例化时,编译会优先选择最匹配特化版本。如果没有找到完全匹配特化版本,编译才会退而求其次,选择更加通用版本。...原因解析 C/C++程序编译链接原理 C/C++程序构建过程通常分为四个阶段:预处理、编译、汇编和链接。...地址问题:如你提到例子,当在a.cpp中没有Add模板具体实例化代码,编译不会生成对应函数。...而在main.obj中尝试使用Add和Add链接会在链接阶段寻找这些函数地址,但因为它们在编译没有被生成,所以链接找不到这些地址,导致链接错误

11410

lnk2001 lnk1120_lnk1120

2.如果使用内联函数是在.CPP文件内定义,而不是在头文件内定义将导致LNK2001错误。   3.调用函数如果所用参数类型同函数声明时类型不符将会产生LNK2001。   ...4.试图从基类构造函数或析构函数调用虚拟函数将会导致LNK2001。   5.要注意函数和变量可公用性,只有全局变量、函数是可公用。 静态函数和静态变量具有相同使用范围限制。...当试图从文件外部访问任何没有在该文件内声明静态变量将导致编译错误或LNK2001。   函数内声明变量(局部变量) 只能在该函数范围内使用。   C++ 全局常量只有静态连接性能。...如果创建C++打开了函数内联(/Ob1或/Ob2),但是在描述该函数相应头文件里却关闭了函数内联(没有inline关键字),这时将得到该错误信息。...导致 LNK2019 常见问题有: 符号声明包含拼写错误,以致于符号声明与符号定义不同。 使用了一个函数,但其参数类型或数量与函数定义不匹配

99320

Visual C++重大更改

若要避免难以检测和诊断运行时错误,我们建议你永远不静态链接使用不同编译版本编译二进制文件。 此外,当你升级 EXE 或 DLL 项目,请确保升级它所链接库。...,因为模板参数类型不匹配模板参数(该参数是指向 const 成员指针,但函数为非 const):           错误 C2893:未能特殊化函数模板“void S2::f(void)” 备注:使用以下模板参数...在 Visual Studio 2015 中 Visual C++ 中,编译将此视为用户定义文字,但由于没有定义匹配用户定义 _x 文本,它将报告错误。           ...在 C++ 中,考虑名称解析候选对象,可能会出现作为潜在匹配项考虑一个或多个名称生成无效模板实例化情况。...这项重大更改会导致本地声明这些函数没有适当 CRT 标头)任何程序发生链接错误(LNK2019、无法解析外部符号)。

5.2K10

Visual C++重大更改

若要避免难以检测和诊断运行时错误,我们建议你永远不静态链接使用不同编译版本编译二进制文件。 此外,当你升级 EXE 或 DLL 项目,请确保升级它所链接库。...,因为模板参数类型不匹配模板参数(该参数是指向 const 成员指针,但函数为非 const):           错误 C2893:未能特殊化函数模板“void S2::f(void)” 备注:使用以下模板参数...在 Visual Studio 2015 中 Visual C++ 中,编译将此视为用户定义文字,但由于没有定义匹配用户定义 _x 文本,它将报告错误。           ...在 C++ 中,考虑名称解析候选对象,可能会出现作为潜在匹配项考虑一个或多个名称生成无效模板实例化情况。...这项重大更改会导致本地声明这些函数没有适当 CRT 标头)任何程序发生链接错误(LNK2019、无法解析外部符号)。

4.7K00

C++】从零开始认识泛型编程 — 模版

当我们定义一个函数模板,我们实际上是在描述一个能够处理多种数据类型算法框架。编译会根据这个框架,在程序中使用模板具体实例,自动生成对应具体类型函数。只有使用了才会生成实例化函数哦!!!!...在编译编译阶段,对于模板函数使用,编译需要根据传入实参类型来推演生成对应类型函数以供调用。...也就是只有使用对应函数才会进行函数实例化,才会进行语法编译,才会报错!!! 没有调用operator[ ],所以operator[ ] 有调用参数不匹配,就没有检查出来。...链接错误 链接错误:是在语法没问题情况下,链接时候,一个函数声明去其他文件寻找函数定义,找不到就会发生链接错误。 那为什么寻找不到呢???明明我们写了函数定义。...因为 a.cpp下函数定义没有实例化,调用函数仅仅是声明知道了使用什么模版类型,而函数定义不知道使用什么模版参数,那自然无法实例化!!!

16310

C++】泛型编程 ② ( 函数模板与普通函数区别 )

等类型 ; 函数模板 可以接受 任何类型 参数 , 函数模板C++ 编译 编译 将类型参数实例化 , 生成对应 普通函数 ; 灵活性 : 普通函数 对于 不同 数据类型参数 需要单独定义...a, T b){} ; 函数模板实例化 : 使用函数模板 , C++ 编译会根据 实际传入 参数类型 自动实例化相应函数 ; 如 : 定义 T add(T a, T b) 类型 函数模板..., 所以 如果使用函数模板处理很多类型 , 需要创建很多普通函数实例 , 会导致编译时间增加 , 代码库增大 ; 维护难度高 : 如果错误使用 函数模板 可能会导致难以查找错误 , 普通函数 更简单..."iostream" using namespace std; // 使用 template 关键字 声明函数模板 // 告诉 C++ 编译 开始使用 泛型编程 // 定义 T 是泛型类型..., 不会进行 类型转换 ; // // 如果 符合 普通函数类型参数要求 , 优先调用普通函数 ; // 如果 没有 符合要求 普通函数 , 则查看 模板函数 能否匹配 ; // 如果 模板函数

22250

C++模板进阶】

、Date 等,模板参数除了可以匹配类型外,还可以匹配常量(非类型),完成如数组、位图等结构大小确定 1.1、使用方法 在定义模板参数,不再使用 class 或 typename,而是直接使用具体类型...通常情况下,模板可以帮我们实现一些与类型无关代码,但在某些场景中,【泛型】无法满足调用精准需求,此时会引发错误,比如使用 日期类对象指针 构建优先级队列后,若不编写对应仿函数,则比较结果会变为未定义...模板不能进行分离编译,会引发链接问题 下面就来谈谈为什么会出现这个问题 3.1、失败原因 声明与定义分离后,在进行链接,无法在符号表中找到目标地址进行跳转,因此链接错误 下面是 模板声明与定义写在同一个文件中...:生成符号表,生成二进制指令 链接:合并段表,将符号表进行合并和重定位,生成可执行程序 当模板 声明 与 定义 分离,因为是 【泛型】,所以编译无法确定函数原型,即 无法生成函数,也就无法获得函数地址...,在符号表中进行函数链接,必然失败 简单举个例子:抛开模板这个东西,在头文件中声明函数,但不定义,调用函数,报就是链接错误 Test.h #pragma once //只声明,不定义 void

16110

浅谈 C++ 元编程

C++ 17 之前,编译测试是通过模板 实例化 和 特化 实现 —— 每次找到最特殊模板进行匹配;而 C++ 17 提出了使用 constexpr-if 编译测试方法。...当调用 _Factor ,编译会展开为 2 * _Factor,然后 _Factor 再展开为 1 * _Factor,最后 _Factor 直接匹配到参数为 0 重载...函数 Sum 有两个重载:一个是对没有函数参数情况,一个是对函数参数个数至少为 1 情况。和定长模板迭代类似,这里也是通过 递归 调用实现参数遍历。...4.2 实例化错误 模板实例化 和 函数绑定 不同:在编译前,前者对传入参数是什么,没有太多限制;而后者则根据函数声明,确定了应该传入参数类型。...这些临时模板是 死代码,即不被执行代码。所以,编译会自动优化最终代码生成,在 链接 (link-time) 移除这些无用代码,使得最终目标代码不会包含它们。

3K61

C++模板进阶

C++ 中设计了非类型模板参数来解决了这个问题,如下,我们可以通过传递不同非类型形参来定义不同类,非类型模板参数在函数模板使用也是如此: template...,如果不同编译可能会报一些奇怪错误。...Data d2; //第二个参数与模板特化中特化参数相同,优先使用特化模板进行实例化 } 可以看到,我们可以将模板部分参数显示指定为某种具体类型,这样模板参数在进行匹配时会优先匹配...stack 进行声明和定义分离,注意: 1、类模板外部成员定义不得具有默认参数,即类模板声明与定义分离不能成员函数不能使用缺省参数; 2、类模板成员函数在分离定义必须指明该函数是属于那个类...;同时,由于 Stack.cpp 里面并没有模板实例化代码,即没有 Stack,也就没有生成具体代码,所以 Stack.cpp 符号表里面函数对应也是无效地址; 4、在链接

43200

c++模板编程解密:C++特化、实例化和分离编译

_array[index]; } 并没有产生编译错误 由于模板这个行为,如果模板某些部分(在本例中是 _size使用没有在代码中被实际使用,那么编译可能不会去实例化或者编译这个部分,它可能不会产生编译错误...但如果没有任何地方使用了这个重载 operator[],编译则不会去检查这部分代码,错误也就没有暴露出来 2.模版特化 函数模版特化 通常情况下,使用模板可以实现一些与类型无关代码,但对于一些特殊类型可能会得到一些错误结果...函数形参表: 必须要和模板函数基础参数类型完全相同,如果不同编译可能会报一些奇怪错误 // 函数模板 -- 参数匹配 template bool Less(T left, T...模板本质上是编译一种生成代码指令集,它们告诉编译如何创建类型或函数特定版本 当你在代码中使用模板,比如创建一个模板对象或调用一个模板函数,编译必须能看到模板整个定义,以便能够实例化模板...实例化过程中,编译器使用具体类型替换模板参数。 对于非模板函数,声明和定义可以分离,因为编译知道函数大小和调用约定,所以它可以在没有函数情况下编译调用函数代码。

45610

C++】格式与实例化操作——详解(7)

用不同类型参数使用函数模板,称为 函数模板实例化 。...【模板参数匹配原则 】 一个非模板函数可以和一个 同名 函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用模板函数而不会从该模板产生出一个实例...【特化使用场景】 特化有其使用需求与场景,但对于一些特殊类型可能会得到一些错误结果,比如:实现了一个专门用来进行小于比较函数模板 用于比较【整型】【日期类Date】,可以正常比较,但要用于比较....obj文件 在.c文件中,编译没有看到到对模板函数实例化,因此不会生成对应函数 最后编译链接阶段会去找函数地址,但是在上一步中函数没有实例化没有生成具体代码,因此报错 4)类模板在C++11...支持声明定义分离 在 C++中,类模板声明和定义必须放在一起,因为编译在编译需要检查类模板具体实现。

9410

C++模板初阶

文章目录 泛型编程 函数模板 1.函数模板使用 2.不同类型传参处理 1.强制类型转换 2.显示实例化 3.多参数模板 3.模板可以和实例函数同时存在,编译优先调用实例函数模板 1.类模板需要显示实例化...地址不同也就是表明它们调用不是同一个函数,所以说它们并不是通过调用函数模板来解决问题,而是调用函数模板根据传参类型经由编译推演以后实例化出来函数 。...---- 2.模板函数和实例函数同时存在,编译优先调用实例函数 ---- 3.如果模板可以生成更匹配函数,则选择模板函数 可以看到这里因为两个参数类型不同,所以编译选择了模板函数。...2.类模板不能声明定义分离 类模板如果定义和声明分离就会出现链接错误:因为类模板没有推演时机必须要我们显示实例化,如果将定义和声明分离就会出现在定义地方没有实例化,而在使用地方虽然有实例化但是没有定义...总之就是我在Test.cpp文件中实例化了该模板调用,但是向上查找却未找到定义,因此就发生了链接错误

61500

第6章 函数

**这里要注意一点,即 C++没有规定实参求值顺序,编译能以任意可行顺序对实参求值。**所以形如下式表达式是错误!...这样的话,如果在头文件中实现了某个函数,而该函数又被多个源文件使用,那么在编译正常,而在链接就会报错,某些函数多次重复定义。...这是因为每个源文件都会对自己使用函数进行编译,编译后 .obj中已经包括了该函数定义,而在后续多个 .obj文件链接,才发现这个函数被多次定义了。...数组不允许拷贝,所以无法以值传递形式传递数组参数;使用数组通常会将其转换成指针,所以当为函数传递一个数组参数,实际传递是指向数组首元素指针。数组大小对函数调用没有影响。...编译依次检查每个实参以确定哪个函数是最佳匹配,如果有且只有一个函数满足下列条件,则匹配成功;否则,编译将报二义性错误。 该函数每个实参匹配都不劣于其他可行函数

1.2K70

连接工具错误lnk2019_2019年十大语文错误

请确保函数调用与声明匹配,并且声明与定义匹配调用模板函数代码还必须拥有包括与定义相同模板参数匹配模板函数声明。 有关模板声明不匹配示例,请参阅示例部分中示例 LNK2019e。...请确保该声明匹配每个符号编译链接。 同样,如果在 C 程序将使用 C++ 文件中定义符号,请在定义中使用 :::no-loc(extern)::: “C” 。...如果你项目没有项目到项目的引用,则可能会收到此链接错误。 添加项目到项目引用以修复此错误。...编译不会生成内联指令,而是生成对 :::no-loc(extern)::: 与内部函数同名 al 符号调用。 当链接尝试找到此缺失函数定义,它会生成 LNK2019。.... // int C::s; int :::no-loc(main):::() { C c; C::s = 1; } 3.声明参数不匹配定义 调用模板函数代码必须拥有匹配模板函数声明

4.1K20

C++从入门到精通——模板

前言 C++模板C++语言中一种泛型编程技术,可以实现在编译期间生成不同类型函数或类。通过使用模板,可以编写通用代码,使其能够处理多种不同类型数据。...模板参数可以在函数模板定义中任何地方使用函数模板实例化是通过在调用函数根据实际参数类型来自动生成具体函数。编译根据调用参数类型匹配合适函数模板实例化,并生成对应函数代码。...所以其实模板就是将本来应该我们做重复事情交给了编译 在编译编译阶段,对于模板函数使用,编译需要根据传入实参类型来推演生成对应类型函数以供调用。...() { Add(1, 2); // 与非模板函数匹配,编译不需要特化 Add(1, 2); // 调用编译特化Add版本 } 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用模板函数而不会从该模板产生出一个实例...总结 都有的情况,优先匹配普通函数+参数匹配 没有普通函数,优先匹配参数匹配+函数模板 只有一个,类型转换一下也能用,也可以匹配调用 template T1 Add

9710

C++模板初阶】

其实很简单,只需要两样东西:编译函数重载 当我们编写好函数模板后,编译会记住这个模板内容,当我们使用模板,编译又会根据参数类型,创建相应、具体函数供参数使用,而这就是函数重载道理...,我们只需要提供蓝图(模板)即可 比如文章开头中 Add 函数,我们提供了模板,当实际调用函数,编译会自动识别参数类型,然后生成对应函数,供参数调用,也就是说,编译根据不同参数,老老实实生成了..._3Addii 而我们参数2为 double ,是一个浮点型数据,实际函数调用时,找是这个函数_3Addid 此时出现明显链接错误,编译索性直接在编译前就已经报错阻拦 解决方法: 将参数2强制类型转换为...使用模板是在麻烦编译帮我们办事,实际事也是办成功 当隐式实例化后函数已存在,不会去生成模板函数,而是直接使用已存在函数 显式实例化后,编译则会优先选择显式生成普通函数 隐式生成模板函数不存在类型隐式类型转换...: 模板类中函数在定义,如果没有在类域中,就需要通过 类模板+ 类域访问 方式定义 类模板 不支持声明与定义分开在两个文件中实现,因为会出现链接错误 ---- 总结 以上就是关于 C++ 模板初阶

12110

C++ 学习笔记

) SFINAE:当函数调用备选方案中出现函数模板,编译根据函数参数确定(替换)函数模板参数类型及返回类型,最后评估替换后函数匹配程度。...替换过程中可能失败,此时编译会忽略掉这一替换结果。 替换和实例化不同,替换只涉及函数函数模板参数类型及返回类型,最后编译选择匹配程度最高函数模板进行实例化。...9.4 破译大篇幅错误信息 预编译头文件不在 c++标 十、模板基本术语 10.1 “类模板”还是“模板类” 10.2 替换,实例化和特例化 替换:在用模板实参去查找匹配模板,会尝试用实参去替换模板参数...模板实参:实例化模板参数传入参数。 十一、泛型库 11.1 可调用对象 c++调用对象类型 a.函数指针 b. 仿函数 c....函数模板可以有 c++链接,但不能有 C 链接函数模板一般具有外部链接,除非是 static 或定义在未命名命名空间中。

6.6K63
领券