[英]let function return template type
我有以下功能
SlabWallConnectionEvent* createObservedEvent(SlabWallConnectionEvent::Data* pEventData)
{
assert(pEventData != nullptr);
return SlabWallConnectionEvent::create(pEventData->m_wall, pEventData->m_slab);
}
然后,我可以使用模板规范从中制作出更通用的模板。
.h文件
template <class ObservedEventType, class ObservedEventDataType>
void createObservedEvent(ObservedEventType*& pEvent,ObservedEventDataType* pEventData);
.cpp文件
template<>
void createObservedEvent<SlabWallConnectionEvent, SlabWallConnectionEvent::Data>
(SlabWallConnectionEvent*& pEvent, SlabWallConnectionEvent::Data* pEventData)
{
assert(pEventData != nullptr);
pEvent = SlabWallConnectionEvent::create(pEventData->m_wall, pEventData->m_slab);
}
这对我来说很完美,但是我对原始指针的引用不太满意。 是否可以将其更改为以下内容:
.h文件
template <class ObservedEventType, class ObservedEventDataType>
ObservedEventType* createObservedEvent(ObservedEventDataType* pEventData);
.cpp文件
template<>
SlabWallConnectionEvent* createObservedEvent<SlabWallConnectionEvent, SlabWallConnectionEvent::Data>
(bim_ui::SlabWallConnectionEvent::Data* pEventData)
{
assert(pEventData != nullptr);
return bim_ui::SlabWallConnectionEvent::create(pEventData->m_wall, pEventData->m_slab);
}
当我尝试使用此方法时,出现以下错误:
Error 1 error C2783: 'ObservedEventType
*createObservedEvent(ObservedEventDataType *)' : could not deduce template
argument for 'ObservedEventType'
编辑
我在模板功能中使用此功能
template <class ObservedEventType>
void CmdBimDrag::observeConnectionEvent(ObservedEventData* pObservedEvent){
...
if (pCurrentEvent == nullptr)
createObservedEvent(pCurrentEvent, pEventData);
...
}
然后该函数被这样调用
observeConnectionEvent<SlabWallConnectionEvent>((*pObservedEventData).get());
编辑2
乔纳斯(Jonas)的答案第一部分仅指定模板类型就足够了:
createObservedEvent<SlabWallConnectionEvent>(pEventData);
但是,使用auto似乎并不能保证删除返回类型的修饰符:
.h文件
template <class ObservedEventType, class ObservedEventDataType>
auto createObservedEvent(ObservedEventDataType* pEventData) -> ObservedEventType*;
.cpp文件
template<>
auto createObservedEvent<SlabWallConnectionEvent, SlabWallConnectionEvent::Data>
(SlabWallConnectionEvent::Data* pEventData) -> SlabWallConnectionEvent*
{
assert(pEventData != nullptr);
return SlabWallConnectionEvent::create(pEventData->m_wall, pEventData->m_slab);
}
该代码使用模板规范进行编译,但仅调用:
createObservedEvent(pEventData);
仍然给出关于无法推断类型的第一个错误。
当你有这个:
template <class ObservedEventType, class ObservedEventDataType>
void createObservedEvent(ObservedEventType*& pEvent,ObservedEventDataType* pEventData);
并这样称呼它:
int *ip;
double *dp;
createObservedEvent(ip, dp);
编译器可以推断ObservedEventType
必须为int
而ObservedEventDataType
必须为double
,因此它将实例化createObservedEvent<int, double>
并对其进行调用。
当您改用它时:
template <class ObservedEventType, class ObservedEventDataType>
ObservedEventType* createObservedEvent(ObservedEventDataType* pEventData);
并称它为
double *dp;
int *ip = createObservedEvent(dp);
编译器可以推断ObservedEventDataType
必须为double
,但不能推断ObservedEventType
应该是什么(因为函数的返回类型和变量的类型不需要完全匹配并且不用于推导)。
为了解决这个问题,您可以手动告诉编译器什么样的ObservedEventType
应该是这样的:
double *dp;
int *ip = createObservedEvent<int>(dp);
现在它知道第一个模板参数ObservedEventType
是int
,因为您这样说,并且ObservedEventDataType
被推导为double
。
您似乎还试图将模板的声明放在标头中,并将定义放入.cpp中,这通常不起作用 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.