让函数返回模板类型

时间:2017-04-07 08:22:35

标签: c++

我有以下功能

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);

然而,使用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);

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

2 个答案:

答案 0 :(得分:2)

您必须具体了解返回类型:

createObservedEvent<SlabWallConnectionEvent>(pEventData);

这是example,使用更简单的类型。

或者,您可以使用auto作为返回类型,并且不包含返回类型的模板参数。在线示例here

答案 1 :(得分:2)

当你有这个:

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应该是什么(因为函数的返回类型和变量的类型不在&# 39; t需要完全匹配,不用于扣除)。

要解决此问题,您可以手动告诉编译器ObservedEventType应该是什么样的:

double *dp;
int *ip = createObservedEvent<int>(dp);

现在它知道第一个模板参数ObservedEventTypeint,因为你是这么说的,ObservedEventDataType被推断为double

您似乎也试图将标题中的模板声明和定义放入。generally doesn't work。。