让函数返回模板类型
问题描述:
我有以下功能让函数返回模板类型
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());
EDIT2
Jonas' answers第一部分工作只是指定的模板类型是不够的:
createObservedEvent<SlabWallConnectionEvent>(pEventData);
但是使用自动似乎并不保证除去返回类型spefication的:
.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这generally doesn't work。
请参见[link](http://*.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file?rq=1) – Jay
由于第一个模板参数不能从调用位置确定(它仅用作返回类型),您需要在调用函数时明确指定该模板参数。 –
第二种解决方案的调用是'auto * pEvent = createObservedEvent(pEventData)'而不是'createObservedEvent(&pEvent,pEventData);'。 –
Jarod42