c++ - 我可以有一个带有可变对象的模板吗?

标签 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看看它是否有帮助,但我完全不明白它在做什么。

最佳答案

C++ does not and won't have static if 功能,您需要变通。

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

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

std::void_t还不是标准的一部分,但实现很简单,可以在链接页面上找到。请确保不要在 std 命名空间上声明它。

proof it works

关于c++ - 我可以有一个带有可变对象的模板吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34733026/

相关文章:

c++ - 成功编译格式错误的程序是否符合标准?

C++ 在运行时获取带有 ID 的对象

c++ - 类成员函数模板可以是虚拟的吗?

c++ - 在 C++ 中从变量指定模板参数

c++ - 从派生类c++获取变量

c++ - 在 C++ 共享库的 header 中声明 'extern "C"' 有什么影响?

c++ - OpenCV 错误 : "LINK : fatal error LNK1104: cannot open file ' opencv_core231d. 库'”

html - gmail 和 outlook 无法正确呈现电子邮件模板

c++派生类型的自动工厂注册

c++ - 使用 C++11 的成员初始化列表中的初始化列表语法