本人在一个类中写了个函数模板(静态的),结果编译报错说无法解析外部符号,该怎么办?
解决方案:5分
可以分开啊,这样:
#include<iostream> using namespace std; class Test{ public: template<typename T> static void compare(const T& v1, const T& v2); }; template<typename T> void Test::compare(const T& v1, const T& v2) { if(v1 < v2) cout << "v1 < v2" << endl; if(v1 > v2) cout << "v1 > v2" << endl; } int main() { Test::compare<int>(2, 3); return 0; }
解决方案:5分
“C++要求模板函数的声明和实现对引用者必须都可见” 但是不是说 你必须要都放在.h 文件中
函数模板的具体实现 可以另放, 例如你可以写一个.hpp
Test.h:
函数模板的具体实现 可以另放, 例如你可以写一个.hpp
Test.h:
#include<iostream> using namespace std; class Test{ public: template<typename T> static void compare(const T& v1, const T& v2); }; #include "Test.hpp"
Test.hpp:
template<typename T> void Test::compare(const T& v1, const T& v2) { if(v1 < v2) cout << "v1 < v2" << endl; if(v1 > v2) cout << "v1 > v2" << endl; }
解决方案:5分
首先本人认为模板函数默认为inine,不管你写不写inline 至于对不对请高手明示
无法解析的外部符号 编译器连接的时候,main函数在生成main.obj 是会导出三个表:
导出符号表 未解决符号表 重定向符号表
原因是本人认为模板函数默认为inine 所以inline这个名称在main.obj 的未解决符号表中,在test.obj 的导出符号表中,所以会提示
该符号在函数 _main 中被引用
而(??$compare@H@Test@@SAXABH0@Z是函数修饰符号,是函数编译时期对函数名的修饰,主要用于函数重载中,想要了解这方面的东西,百度搜 stdcall cdecl,跟这里没啥关系本人就不说了
至于为什么在main.obj 的未解决符号表中,在test.obj 的导出符号表 是原因是 inline修饰的类成员函数是内部链接,简单的说是test。obj这个编译单元才可见,main.obj不可见,所以才会提示 符号在函数 _main 中被引用
详细信息请搜,内部链接和外部链接
最后府上本人为什么认为模板函数默认为inine 的代码
无法解析的外部符号 编译器连接的时候,main函数在生成main.obj 是会导出三个表:
导出符号表 未解决符号表 重定向符号表
原因是本人认为模板函数默认为inine 所以inline这个名称在main.obj 的未解决符号表中,在test.obj 的导出符号表中,所以会提示
该符号在函数 _main 中被引用
而(??$compare@H@Test@@SAXABH0@Z是函数修饰符号,是函数编译时期对函数名的修饰,主要用于函数重载中,想要了解这方面的东西,百度搜 stdcall cdecl,跟这里没啥关系本人就不说了
至于为什么在main.obj 的未解决符号表中,在test.obj 的导出符号表 是原因是 inline修饰的类成员函数是内部链接,简单的说是test。obj这个编译单元才可见,main.obj不可见,所以才会提示 符号在函数 _main 中被引用
详细信息请搜,内部链接和外部链接
最后府上本人为什么认为模板函数默认为inine 的代码
///第一个没错 第二个第三个报错->该符号在函数 _main 中被引用 pragma once class Test{ public: static int compare(const int v1, const int v2); }; #include "funch.h" int Test::compare(const int v1, const int v2) { return v1+v2; } /////////////////////////// #pragma once class Test{ public: static int compare(const int v1, const int v2); }; #include "funch.h" inline int Test::compare(const int v1, const int v2) { return v1+v2; } ////////////////////// #pragma once class Test{ public: template<typename T> static T compare(const T v1, const T v2); }; #include "funch.h" template<typename T> T Test::compare(const T v1, const T v2)//加不加都是inline { return v1+v2; }
最后吐槽下 20分好少
解决方案:5分
++
PS:有些人不了解不要说不能分开到声明.h, 实现在.cpp,9L说的很对。
只有符合这个条件管你是放在哪里。
放在一起(头文件)一般只是考虑外部调用的情况,仅此而已。
PS:有些人不了解不要说不能分开到声明.h, 实现在.cpp,9L说的很对。
只有符合这个条件管你是放在哪里。
放在一起(头文件)一般只是考虑外部调用的情况,仅此而已。