3

我如何重写此代码,以便用户在通过有效方向时始终显示正确的状态(CA、AL 等)字符串。

即,我如何确保在编译期间而不是在运行时,方向枚举中的每个 enum_types 都有一个有效的 case 语句?

为了。例如。我特意注释掉了东部的案例陈述。有没有办法在编译时捕获它。

我的直觉是(否)这就是语言提供默认情况的原因,因此这可能是不可能的。但我会把这个留给专家。

#include <iostream>
#include <string>

using namespace::std;

typedef enum 
{
    min_dir = -1,
    north,
    south,
    east,
    west,
}directions;

directions get_direction( string user_choice)
{
    if(user_choice == "north")
    {
        return north;
    }
    else if (user_choice == "south")
    {
        return south;   
    }
    else if (user_choice == "east")
    {
        return east;    
    }
    else if (user_choice == "west")
    {
        return west;    
    }
    else 
    {
        return min_dir;
    }
}

int main()
{
    string user_direction;
    cout << "Enter direction\n";
    cin >> user_direction;

    directions my_dir = get_direction(user_direction);
    cout << " Print direction's description\n";

    if( my_dir == min_dir)
    {
        // User passed junk
        return -1;
    }

    switch(my_dir)
    {
    case north:
        cout << "North - New york\n";break;
    case south:
        cout << "South - Alabama\n";break;
//  case east:
//      cout << "East - North Carolina\n";break;
    case west:
        cout << "West - California\n";break;
    default:
        cout << "Should Ideally never get here\n";break;
    }
    system("pause");
    return 0;
}

编辑:这只是说明这一点的一个例子。这适用于工作中的代码。他们已经在 Windows(MSVC)和 linux(gcc)中编译了这个。这只是一个警告吗?我需要更严格的执法。

如果枚举没有 case 语句,我可以编写一些在 make 过程中出错的代码吗?

4

2 回答 2

5

在 GCC (g++) 和 Clang 中,有-Wswitch-enum, 如果您没有 a caseforenum您正在switch处理的类型的可能值(即使您有default案例),它会警告您。

在 MSVC 中,有类似的C4062default来自警告级别 3,但如果您有声明,它不会警告您。如果在这种情况下需要警告,则需要启用级别 4 警告C4061,即使提供了默认情况,它也会在缺少枚举值时生成警告。

就使其成为错误而言:所有编译器都有一个“将警告视为错误”选项。在 GCC 和 Clang 中,它是-Werror; 在 MSVC 中,它是/WX.

于 2012-11-13T01:56:21.650 回答
1

如果您使用一个函数数组,该数组的大小与您的枚举相符并在声明时进行了初始化,那么您可以对数组的大小与枚举计数进行静态断言,以验证所有成员是否存在。通过在数组中使用仿函数而不是函数指针,您还可以确定您没有提供 nullptr 作为值,因为每个仿函数都将被构造。

typedef enum 
{
    min_dir = -1,
    north = 0,
    south,
    count_dir
}directions;

class GoDir
{
public:
    virtual void operator()() {}
};

class GoNorth : public GoDir
{
public:
    virtual void operator()() {}
};

class GoSouth : public GoDir
{
public:
    virtual void operator()() {}
};

static GoDir actions[count_dir] = {GoNorth(), GoSouth()};
static_assert(sizeof(actions)/sizeof(actions[0]) == count_dir, "Error");
于 2012-11-13T02:22:42.320 回答