typedef转模板:Solaris环境下C++函数模板未定义问题求助
问题分析与解决方案
问题背景
在Solaris环境下实现了重载函数模板,相关代码及报错信息如下:
核心代码
typedef AISObject *(*factorywv)(); namespace bcMwMrsh { template<typename listT> void cppListFromWire(void *&src,RWTValSlist<listT> &dest, factorywv); } int FormAccountSetupList::fromWire(void *&buf, long bufLen) { bcMwMrsh::cppListFromWire(buf, contents, FormAccountSetupRow::AISFactory); return 0; }
关联定义
static AISObject *AISFactory() { return new FormAccountSetupList; } RWTValSlist<FormAccountSetupRow *> contents;
报错信息
Undefined first referenced symbol in file void bcMwMrsh::cppListFromWire<FormATMSetupRow*>(void*&, RWTValSlist<FormATMSetupRow*, std::allocator<FormATMSetupRow*> >&, AISObject* (*)()) actsetup.o
错误原因
出现未定义符号的核心原因是模板函数的定义未被编译器可见,导致特定类型的实例化未生成:
- 若
cppListFromWire的模板实现放在.cpp文件而非头文件中,调用处无法生成FormATMSetupRow*对应的实例; - 当前的
factorywv是固定指向返回AISObject*的函数指针,当处理FormATMSetupRow*类型时,工厂函数的返回类型与容器元素类型不匹配,也会导致实例化失败。
解决方案
1. 将typedef转换为模板别名
把固定的函数指针typedef改成模板形式,适配不同的返回类型:
template<typename T> using factorywv = T*(*)();
2. 调整模板函数的参数定义
修改cppListFromWire的模板定义,让工厂函数的返回类型与容器元素类型listT匹配:
namespace bcMwMrsh { template<typename listT> void cppListFromWire(void *&src, RWTValSlist<listT> &dest, factorywv<listT> factory); }
3. 确保模板实现可见
- 优先把
cppListFromWire的模板实现(函数体)放在头文件中,让所有调用处的编译器都能生成对应类型的实例; - 若必须放在.cpp文件中,需显式实例化所需类型,比如在模板实现的.cpp文件末尾添加:
namespace bcMwMrsh { template void cppListFromWire<FormAccountSetupRow*>(void*&, RWTValSlist<FormAccountSetupRow*>&, factorywv<FormAccountSetupRow*>); template void cppListFromWire<FormATMSetupRow*>(void*&, RWTValSlist<FormATMSetupRow*>&, factorywv<FormATMSetupRow*>); }
4. 修正工厂函数的返回类型
确保工厂函数的返回类型与容器元素类型一致,比如FormATMSetupRow的工厂函数应返回对应类型指针:
static FormATMSetupRow *AISFactory() { return new FormATMSetupRow; }
内容的提问来源于stack exchange,提问作者Puneeth
相关产品推荐
相关产品推荐

