c++ - 定义基于模板的映射指针,以便在验证范围时将 int 解析为 enum

标签 c++ templates pointers dictionary enums

我想提供一种简单的机制,将 int 转换为枚举类型,并在此过程中提供一些错误检查。这将确保 int 不会超出其声明的枚举范围。我想出了以下函数,它利用 std::map:

#include <map>
#include <type_traits>

enum A
{
    a = 0,
    b,
    c
};

enum B
{
    d = 10,
    e,
    f
};

std::map<int, A> mA;
std::map<int, B> mB;

template<typename T> T ParseEnum(int nVal)
{
    std::map<int, T>* p;

    if (std::is_same<T, A>::value)
        p = &mA; //compiler error

    else if (std::is_same<T, B>::value)
        p = &mB; //compiler error

    return static_cast<T>(p->at(nVal));
}


int _tmain(int argc, _TCHAR* argv[])
{
    mA.insert(std::pair<int, A>(0, A::a));
    mA.insert(std::pair<int, A>(1, A::b));
    mA.insert(std::pair<int, A>(2, A::c));

    mB.insert(std::pair<int, B>(10, B::d));
    mB.insert(std::pair<int, B>(11, B::e));
    mB.insert(std::pair<int, B>(12, B::f));

    try
    {
        A eA = ParseEnum<A>(1); //ok, should resolve to A::b;

        B eB = ParseEnum<B>(16); //should throw an exception;
    }
    catch (std::out_of_range&)
    {

    }

    return 0;
}

不幸的是,我在将 map 引用分配给基于模板的 map 指针时遇到问题,如以下编译器错误所示:

error C2440: '=' : cannot convert from 'std::map<int,A,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> *' to 'std::map<int,B,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> *'

error C2440: '=' : cannot convert from 'std::map<int,B,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> *' to 'std::map<int,A,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> *'

有没有办法定义这样一个基于模板的指针,还是我运气不好?

最佳答案

模板特化更适合:

//declare the ParseEnum function template
template<typename T> 
T ParseEnum(int nVal);

//specialization for when ParseEnum is instantiated with A
template<>
A ParseEnum<A> (int nVal)
{
    return mA.at(nVal);
}

//specialization for B
template<>
B ParseEnum<B> (int nVal)
{
    return mB.at(nVal);
}

或者这可能更灵活。它创建一个 struct ,它将保存对其模板参数对应的 map 的引用:

//declare a struct which will hold a reference to the map we want
template <typename T>
struct GetMap
{
    static std::map<int,T> &map;
};

//when instantiated with A, the map member is a reference to mA
template<>
std::map<int,A> &GetMap<A>::map = mA;

//similarly for B and mB
template<>
std::map<int,B> &GetMap<B>::map = mB;

template<typename T> T ParseEnum(int nVal)
{
    //GetMap<T>::map will be a reference to the correct map
    return GetMap<T>::map.at(nVal);
}

关于c++ - 定义基于模板的映射指针,以便在验证范围时将 int 解析为 enum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28967807/

相关文章:

c++ - OpenGL 多重纹理 - glActiveTexture 为 NULL

c++ - Hook ntdll.dll 调用的问题

具有静态类成员的 C++ 模板类

c++ - 模板化 map /字典实现

asp.net-mvc-3 - 可重用的编辑器模板,带有用于业务对象的 DropDownList

pointers - COBOL中处理不同长度的参数

c - 将指针传递给函数但指针保持不变

c++ - 线程连接问题

c++ - 运行 OPNet 项目时出现错误

objective-c - 修改传递给方法的函数指针?