繁体   English   中英

让函数返回模板类型

[英]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);

仍然给出关于无法推断类型的第一个错误。

您必须具体说明返回类型:

createObservedEvent<SlabWallConnectionEvent>(pEventData);

这是使用更简单类型的示例

另外,您可以将auto用作返回类型,而不为返回类型包含模板参数。 在线示例在这里

当你有这个:

template <class ObservedEventType, class ObservedEventDataType>
void createObservedEvent(ObservedEventType*& pEvent,ObservedEventDataType* pEventData);

并这样称呼它:

int *ip;
double *dp;
createObservedEvent(ip, dp);

编译器可以推断ObservedEventType必须为intObservedEventDataType必须为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);

现在它知道第一个模板参数ObservedEventTypeint ,因为您这样说,并且ObservedEventDataType被推导为double


您似乎还试图将模板的声明放在标头中,并将定义放入.cpp中,这通常不起作用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM