我可以使用带有变量对象的单个模板吗?

时间:2016-01-11 23:26:52

标签: c++ templates

我目前有以下代码:

template< class Obj, class ObjResult >
CLStatus convertObjToResult2( const Obj & xFrom, ObjResult & xTo )
{
    CLStatus eStatus = CLSTATUS_SUCCESS;
    switch ( xTo.eType )
    {
        case CEPTFull:
            xTo.xData.xFull = xFrom;
            break;
        case CEPTBrief:
            eStatus = Convert( xFrom, xTo.xData.xBrief );
            break;
        default:
            eStatus = CLSTATUS_INVALIDPROJECTIONTYPE;
    }
    return eStatus;
}

template< class Obj, class ObjResult >
CLStatus convertObjToResult1( const Obj & xFrom, ObjResult & xTo )
{
    CLStatus eStatus = CLSTATUS_SUCCESS;
    switch ( xTo.eType )
    {
        case CEPTFull:
            xTo.xData.xFull = xFrom;
            break;
        default:
            eStatus = CLSTATUS_INVALIDPROJECTIONTYPE;
    }
    return eStatus;
}

所有ObjResults都有一个xFull,但只有一些有xBrief,其中xData是union。这导致我在上面写了两个不同的模板,但如果我能以某种方式只有一个模板那就太棒了。

我不能简单地使用convertObjToResult2,因为它无法使用没有xBrief的对象类型进行编译。我查看了this answer,看看它是否会有所帮助,但我根本不了解它在做什么。

1 个答案:

答案 0 :(得分:2)

Logger logger = LogManager.GetCurrentClassLogger() does not and won't have C++功能以来,您需要解决此问题。

如果你不能像评论中所说的那样重载static if,我想到了它上面的一个层,可以根据Convert是否有成员而专门化。

ObjResult

std::void_t尚未成为标准的一部分,但实现很简单,可以在链接页面上找到。请确保不要在template <class Obj, class ObjResult, class = void> struct ConvertIfHasBrief { static auto Convert(Obj const &, ObjResult &) -> CLStatus { return {};// dymmy value, not used } }; template <class Obj, class ObjResult> struct ConvertIfHasBrief <Obj, ObjResult, std::void_t<decltype(std::declval<ObjResult>().xData.xBrief)>> { static auto Convert(Obj const &xFrom, ObjResult &xTo) { return ::Convert(xFrom, xTo.xData.xBrief); } }; template< class Obj, class ObjResult> CLStatus convertObjToResult( const Obj & xFrom, ObjResult & xTo ) { CLStatus eStatus = CLSTATUS_SUCCESS; switch ( xTo.eType ) { case CEPTFull: xTo.xData.xFull = xFrom; break; case CEPTBrief: eStatus = ConvertIfHasBrief<Obj, ObjResult>::Convert(xFrom, xTo); break; default: eStatus = CLSTATUS_INVALIDPROJECTIONTYPE; } return eStatus; } 命名空间声明它。

proof it works