我正在寻找一种针对以下问题的hacky解决方案: GCC 4.4+接受以下c ++ 0x代码:
enum class my_enum
{
value1,
value2
};
允许这样使用:
my_enum e = my_enum::value1;
这带来了所有的钟声和口哨声。我想使这段代码与MSVC 2010兼容,使用语法不会改变。我已经在here之前对此进行了思考,并且接受的答案有效,但是枚举和枚举值的两个不同名称的需要正在破坏这两种方法的兼容性。这使得它当然无法替换C ++ 0x代码。我想知道是否有一些#undef
和#define
技巧可以解决这个问题,允许我使用 enum class
- 就像语法一样(可能没有严格的类型安全等) ,但至少相同的语法。谢谢!
答案 0 :(得分:21)
我刚刚发现詹姆斯的好黑客(我以前一直在使用)的问题,并解决了这个问题。当我尝试为my_enum定义流操作符时,我发现了这个问题。
#include <iostream>
struct my_enum {
enum type {
value1,
value2
};
my_enum(type v) : value_(v) { }
operator type() const { return value_; }
private:
type value_;
};
std::ostream&
operator<<(std::ostream& os, my_enum v)
{
return os << "streaming my_enum";
}
int main()
{
std::cout << my_enum::value1 << '\n';
}
输出结果为:
0
问题是my_enum::value1
的类型与my_enum
不同。这是詹姆斯的黑客攻击我想出来的。
struct my_enum
{
static const my_enum value1;
static const my_enum value2;
explicit my_enum(int v) : value_(v) { }
// explicit // if you have it!
operator int() const { return value_; }
private:
int value_;
};
my_enum const my_enum::value1(0);
my_enum const my_enum::value2(1);
注意:
int
。答案 1 :(得分:5)
请勿使用此解决方案。请参阅霍华德接受的答案以获得更好的解决方案。我要离开这篇文章,因为霍华德的回答是指它。
如果您需要能够使用尚不支持新的,尚未标准或尚未广泛实现的语言功能的编译器来编译代码,则最好避免在代码中使用该语言功能。
也就是说,作为黑客解决方法,您可以将enum
打包在struct
中并使用一对隐式转换:
struct my_enum {
enum type {
value1,
value2
};
my_enum(type v) : value_(v) { }
operator type() const { return value_; }
private:
type value_;
};
答案 2 :(得分:0)
我一直在争取一整天找到一个真正的最佳解决方案,但似乎没有一个。我需要我的枚举
switch
声明提出以下代码,建立在Howard 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.");
}
}
不是特别好,但是它确实如此好,我猜......