C ++使用模板为特定的枚举值创建方法

时间:2015-02-21 23:36:28

标签: c++ templates enums

我想编写一个方法,让编译器根据特定的枚举值生成多个方法。

下面我有一些isValid *()方法。它们都具有您所看到的相同结构,因此我希望将它们组合成一种方法。也许模板对此有用吗?也许不是。

像这样的伪代码(为清晰起见而编辑):

enum Dir { East, West, South, North }

bool isValidFromWest(const Dir dir)
{
  switch (dir)
  {
    case West:    return foo(dir);
    case East:    return true;
    case North:   return false;
    case South:   return false;
  }
}

bool isValidFromEast(const Dir dir)
{
  switch (dir)
  {
    case East:    return foo(dir);
    case West:    return true;
    case North:   return false;
    case South:   return false;
  }
}

bool isValidFromSouth(const Dir dir)
{
  switch (dir)
  {
    case South:   return foo(dir);
    case North:   return true;
    case West:    return false;
    case East:    return false;
  }
}

bool isValidFromNorth(const Dir dir)
{
  switch (dir)
  {
    case North:   return foo(dir);
    case South:   return true;
    case West:    return false;
    case East:    return false;
  }
}

是否有一种编译时方法将这些方法组合到一个保持性能的方法中,并且不会牺牲太多的代码清晰度。

2 个答案:

答案 0 :(得分:0)

模板选择发生在传递给模板函数/用户定义类型的类型之上,而不是取决于枚举等值。

如果您只想切换枚举,则不需要模板,代码如下:

#include<iostream> 
enum Dir { East, West };


void doStuff()
{
    std::cout<<"doStuff"<<std::endl;
}
// This method should be resolved at compile time
void  opposite()
{
   std::cout<<"Opposite"<<std::endl;
}



void  isValid(const Dir dir)
{
  switch (dir)
  {
    case East:
       doStuff();
    case West:
        opposite();

  }
}
int main()
{
    isValid(East);
    return 0;
}

答案 1 :(得分:0)

模板在这种情况下很有用,以下代码可能符合您的要求。

为简化起见,有必要手动将enum Dir的值更改为某些特殊值(两个相反方向的总和为零)。

enum Dir{East = -2, West = 2, South = -1, North = 1};

bool foo(const Dir dir)
{
    //Do something
    return false;
}

template< Dir n >
struct CalDir
{
    static bool isValid(const Dir dir)
    {
        switch (dir)
        {
        case n:     return foo(dir);
        case 0 - n: return true;
        default:    return false;
        }
    }
};

int main()
{
    Dir a = East;
    CalDir<East>::isValid(a); //Equivalents to isValidFromWest(a)
    Dir b = North;
    CalDir<South>::isValid(b);//equivalents to isValidFromSouth(b)

    return 0;
}