为什么我在尝试创建 std::numpunct 衍生物的实例时出现链接错误<char16_t>?
Why do I get link errors when trying to create an instance of std::numpunct<char16_t> derivative?
我正在尝试将std::basic_stringstream<char16_t>
与基于UTF16的std::numpunct
一起使用。但是,创建std::numpunct<char16_t>
的最简单可能的导数的尝试在链接阶段失败了。这是代码:
#include <locale>
struct my_punct : public std::numpunct<char16_t> {};
int main()
{
my_punct n;
}
以下是链接错误(使用g++7.2.0)(实时测试):
$ g++-7 test0.cpp -o test
/tmp/cc0oWPhL.o: In function `std::numpunct<char16_t>::numpunct(unsigned int)':
test0.cpp:(.text._ZNSt8numpunctIDsEC2Ej[_ZNSt8numpunctIDsEC5Ej]+0x36): undefined reference to `std::numpunct<char16_t>::_M_initialize_numpunct(__locale_struct*)'
/tmp/cc0oWPhL.o: In function `my_punct::~my_punct()':
test0.cpp:(.text._ZN8my_punctD2Ev[_ZN8my_punctD5Ev]+0x18): undefined reference to `std::numpunct<char16_t>::~numpunct()'
/tmp/cc0oWPhL.o:(.rodata._ZTVSt8numpunctIDsE[_ZTVSt8numpunctIDsE]+0x8): undefined reference to `std::numpunct<char16_t>::~numpunct()'
/tmp/cc0oWPhL.o:(.rodata._ZTVSt8numpunctIDsE[_ZTVSt8numpunctIDsE]+0xc): undefined reference to `std::numpunct<char16_t>::~numpunct()'
collect2: error: ld returned 1 exit status
如果我将char16_t
更改为char
,则链接成功完成。那么,我在这里做错了什么?我需要一些额外的库来链接吗?
作为健全性检查,我尝试过为_ZTVSt8numpunctIDsE
进行GCC安装,但没有结果。但对CCD_ 7的搜索确实找到了CCD_ 8。这是否意味着我在libstdc++中发现了一个错误?
这是因为没有专门类的支持实现。当您使用模板时,编译器会为特定用途生成一个符号。如果已经有一个预定义的、完全模板化的实现,那么编译器可以进行自己的定义,但前提是它在编译试图使用模板化实现的文件时看到了模板化实现。如果看不到,那么它只会创建符号,使其未定义,并期望稍后链接它。
举个简单的例子。。。
在Template_Add.h中
// Generic template
template< class T >
T add(T first, T second);
在Template_Add.cpp中
// Specialized for int
template<>
int add<int>(int first, int second){
在main.cpp中
#include "Template_Add.h"
int main(){
int ia, ib, ic;
double da, db, dc;
ia = 3;
ib = 4;
da = 3.0;
db = 4.0;
// we expect ia = 7, and works
ic = add(ib, ic);
// we expect dc = 7.0, but doesn't work
// this will result in an unresolved symbol
dc = add(da, db);
return 0;
}
这种行为的原因是main.cpp
可以看到的任何地方都不存在模板化实现。然而,当所有内容都被链接时,链接器会看到存在"int add(int,int)",因此这是允许的。
如果您拥有模板,那么您可以将(模板化的)实现添加到包含模板声明的.h文件中。这样编译器就知道如何在编译时生成符号和定义。为了修复上面的例子,我们可以将以下代码添加到Template_add.h中:
template< class T >
T add(T first, T second){
return first + second;
}
然后,包括"Template_Add.h"在内的任何东西都可以为任何试图使用该模板的东西生成自己的实现。
如果你没有模板,那么你能做的最好的事情就是找到一种方法来使用支持的模板专业化。在这种情况下,最好将char16_t
强制转换(或typedef)为short
,然后看看这是否有效。
- Netbeans 10:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- CMake 错误:链接器命令失败,退出代码为 1 和 cpp.o 文件
- clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) - 体系结构的未定义符号 x86_64:
- 如何修复 clang: 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- Android NDK.Build命令失败.未定义的引用.clang++:错误:链接器命令失败,退出代码为1
- 使用cmake错误链接boost日志
- 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用):在 Macbook 上
- C++ XCODE ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -
- clang:错误:链接器命令失败,C++代码中的退出代码为 1(使用 -v 查看调用)
- 静态库中的 g++ 错误链接函数
- 未定义的参考错误链接天然函数Android
- C++编译错误:ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -v
- QT Q_PROPERTY错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- OSX MOJAVE -LD:架构X86_64 clang找不到符号:错误:链接器命令失败,出口代码1
- C 错误链接器命令失败了出口代码1(使用-V查看调用)
- LD:架构x86_64 clang找不到符号:错误:链接器命令失败,出口代码1(使用-v to See
- 聚输出错误 - 链接列表
- Xcode链接器错误:链接器命令失败,退出代码为1(使用-v查看调用)
- 尝试构建C DLIB示例无法与数百个未定义的参考错误链接