在运行时解析枚举模板参数 [英] Resolve enum template parameters at run-time

查看:128
本文介绍了在运行时解析枚举模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图想出一个逻辑,需要多个枚举,并确定一个结构类型和其对应的大小传递给第三方组件,我正在考虑使用traits来解决这个问题在一个干净方式:

I am trying to come up with a piece of logic that takes multiple enums and determine a struct type and its corresponding size to pass to a third-party component, and I am considering to use traits to solve this issue in a clean way:

强力解决方案(使用一个枚举)看起来像这样:

A brute force solution (using one enum) looks something like this:

typedef enum FOO_TYPE
{
    FOO_TYPE_0 = 0,
    FOO_TYPE_1 = 1,
    ...
} FOO_TYPE;

switch (m_foo)
{
    case (FOO_TYPE_0):
    {
        FOO_0 Foo = {};
        UINT size = sizeof(Foo);
        m_thirdParty->CallFunction(&Foo, size);
    }
    break;

    case (FOO_TYPE_1):
    ...
}


$ b b

我考虑使用traits通过为每个FOO_TYPE定义特殊化来解决这个问题,但是在编译期间遇到了问题,因为我在运行时而不是在编译时选择模板的特殊化。然而,它不是立即显而易见的我如何可以解决这个,而不会导致switch语句的成本(当你考虑多个枚举类型时,它的增长非常快)上面。如果有任何人有想法,请让我知道。

I considered using traits to solve this issue by defining specialization for each FOO_TYPE, but hit the issue during compilation because I am picking the specializations of the templates at run-time instead of at compile-time. However, it's not immediately obvious to me how I could resolve this without incurring the cost of the switch statement (which grows very quickly when you consider multiple enum types) above. If anyone has ideas, please let me know.

template <FOO_TYPE FooType> 
struct FooTraits;

template <>
struct FooTraits<FOO_TYPE_0>
{
    typedef FOO_0 FooStruct;
};

{
    typedef FooTraits<m_foo> FooTraitsType; <== THIS USAGE CAUSES COMPILATION ERRORS
    FooTraitsType::FooStruct Foo = {};
    UINT size = sizeof(FooTraitsType::FooStruct);
    m_thirdParty->CallFunction(&Foo, size);
}

感谢。

推荐答案

你不能在运行时使用模板,但你有一些其他选项,你可以使用本地化的变化。

You cant do this at run-time using templates, but you do have some other options you can use localise the changes.

我的偏好是使用多态性:

My preference would be to use polymorphism:

class Foo {
  static Foo* createFoo(FOO_TYPE type) {
  switch(type) {
     case FOO_TYPE_0:
       return new FooType0();
     case FOO_TYPE_1:
       return new FooType1();
  }
  virtual void callFunction(ThridParty thirdParty)=0;
}

class FooType0 : public Foo {
   void callFunction(ThridParty thirdParty) {
      FOO_0 Foo = {};
      UINT size = sizeof(Foo);
      m_thirdParty->CallFunction(&Foo, size);
   } 
}

class FooType1 : public Foo {
   void callFunction(ThridParty thirdParty) {
      FOO_1 Foo = {};
      UINT size = sizeof(Foo);
      m_thirdParty->CallFunction(&Foo, size);
   } 
}

您的交换机块将变为:

// Note this leaks ... see below for non-leaking version.
createFoo(m_foo)->callFunction(m_thirdParty);

现在每个FooTypeX类都有一些丑陋的重复,所以你可以通过模板化来删除它: / p>

Now there's some ugly duplication in each of the FooTypeX classes, so you can remove that with templatization:

class Foo {
  static Foo* createFoo(FOO_TYPE type) {
  switch(type) {
     case FOO_TYPE_0:
       return new FooX<FOO_1>();
     case FOO_TYPE_1:
       return new FooX<FOO_2>();
  }
  virtual void callFunction(ThridParty thirdParty)=0;
}

class FooX<BaseStruct> : public Foo {
   void callFunction(ThridParty thirdParty) {
      BaseStruct foo = {};
      UINT size = sizeof(foo);
      m_thirdParty->CallFunction(&foo, size);
   } 
} 

// A bit of a hack to prevent leaking. In real code you may want to 
// handle ownership differently.
std::unique_ptr<Foo>(createFoo(m_foo))->callFunction(m_thirdParty);

这篇关于在运行时解析枚举模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆