我想提供一种简单的机制,将 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> ↦
};
//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/