我一直在争取一整天,找到一个真正的最佳解决方案,但似乎并没有一个。我需要我的枚举是
- 不隐式转换为整型
- 可用在
switch
声明
- 可用作非类型模板参数
在纷纷拿出以下码,在霍华德Hinnant(欣南特)的解决方案内置:
struct DataType
{
struct integral {
enum type { None, Single, Double, Int };
};
typedef typename integral::type integral_type;
explicit DataType(integral_type v) : val(v) {}
integral_type integral_value() const { return val; }
bool operator==(const DataType& s) const { return val == s.val; }
bool operator!=(const DataType& s) const { return val != s.val; }
static const DataType None;
static const DataType Single;
static const DataType Double;
static const DataType Int;
private:
integral_type val;
};
在.cpp
文件:
const DataType DataType::None (DataType::integral::None);
const DataType DataType::Single (DataType::integral::Single);
const DataType DataType::Double (DataType::integral::Double);
const DataType DataType::Int (DataType::integral::Int);
作为非类型模板参数:
template <DataType::integral_type>
struct DataTypeTraits;
template <>
struct DataTypeTraits<DataType::integral::Single>
{
enum { size = 4 };
};
在开关:
size_t get_size(DataType type)
{
switch (type.integral_value()) {
case DataType::integral::Single: return DataTypeTraits<DataType::integral::Single>::size;
case DataType::integral::Double: return DataTypeTraits<DataType::integral::Double>::size;
case DataType::integral::Int: return DataTypeTraits<DataType::integral::Int>::size;
default: throw std::logic_error("Unknown data type.");
}
}
不是特别大,但是这是好得不能再好,我猜。 ..
这是一种模式?你为什么认为这是一个黑客?它很整洁。 – Inverse 2011-02-12 21:09:23
@反:如果你反复使用它会成为一种模式:-)。在结构体或命名空间中枚举枚举以防止名称空间污染是一种常用技术,我一直使用(主要是)。使用隐式转换来允许使用封装结构,就好像它是枚举一样,这不是一种常见模式,至少在我没有阅读过的任何代码中都是如此。由于隐含转换,我对此保持警惕:我不断发现隐式转换允许您编写细微代码的不同方式...... – 2011-02-13 15:14:50