我在代码语句周围使用了一个宏来引入嵌套异常处理:
#define TRAP_EXCEPTION(statement) \
try \
{ \
try{statement} \
catch(Engine::Exception& e) \
{ \
throw MyException(e.message()); \
} \
}
在一个案例引发编译器错误之前,这一直运行良好。我设法构建了一个最小的例子:
TRAP_EXCEPTION
(
std::map<MyType, bool> Map;
)
catch(MyException& e)
{
}
这会产生以下错误......我该如何修复它(理想情况下在宏中)?
> error C2143: syntax error : missing '>' before '}'
> error C2976: 'std::map' : too few template arguments
> error C2143: syntax error : missing ';' before '}'
答案 0 :(得分:5)
宏不理解模板参数(尖括号是精确的),他们只看到,
并认为你为宏提供了两个不同的参数。您需要添加圆括号:
TRAP_EXCEPTION
(
(std::map<MyType, bool> Map;)
)
并且需要更改宏:
#define UNWRAP(...) __VA_ARGS__
#define TRAP_EXCEPTION(statement) \
try \
{ \
try{UNWRAP statement} \
catch(Engine::Exception& e) \
{ \
throw MyException(e.message()); \
} \
}
请注意,这需要您始终在通话方提供一对额外的圆括号。
在你的情况下(因为宏只应该只有一个语句),你也可以使用一个可变参数宏:
#define TRAP_EXCEPTION(...) \
try \
{ \
try{ __VA_ARGS__ } \
catch(Engine::Exception& e) \
{ \
throw MyException(e.message()); \
} \
}
这可能更好,因为呼叫方没有改变和
TRAP_EXCEPTION
(
std::map<MyType, bool> Map;
)
现在可以正常使用。
答案 1 :(得分:3)
预处理器不会将<
和>
识别为括号,因此将逗号解释为宏参数分隔符。如果语句因任何其他原因包含未加括号的逗号(例如逗号运算符或逗号分隔声明符),则会出现同样的问题。
如果你真的想滥用这样的预处理器,你可以提出它接受任意数量的宏参数:
#define TRAP_EXCEPTION(...) \
try \
{ \
try{__VA_ARGS__} \
catch(Engine::Exception& e) \
{ \
throw MyException(e.message()); \
} \
}
但我建议你不要尝试用宏做任何聪明的事。
答案 2 :(得分:3)
您可以在宏之前使用typedef,而不是__VA_ARGS__
技巧。
__VA_ARGS__
技巧有一些缺点。
typedef std::map<MyType, bool> MyMap;
TRAP_EXCEPTION(
MyMap Map;
)