我希望能够实现:
#define GET_VALUE_OR_RETURN(value, expect) do { if (expect.valid()) \
{ value = move(expect.get()); } else return expect.get_error();break;} while(0)
expect是一个具有宏中使用的成员的类实例。如果valid()为false,我将从当前函数返回,否则检索该值。
通过使用已定义的宏,我有这种用法语法:
auto expect = CreateInstance(someData);
ResultType result;
GET_EXPECTED_VALUE_OR_RETURN(result, expect);
使用此语法的缺点是我必须在使用宏之前默认初始化ResultType,并且仅使用2行代码才能使用有效值初始化我的变量。还有更好的东西吗?
答案 0 :(得分:2)
如果您愿意将宏扩展为多个语句,那么这是一个解决方案:
#define GET_VALUE_OR_RETURN(value, expect) \
if (!(expect).valid()) return (expect).get_error(); \
value = move((expect).get())
使用:
auto expect = CreateInstance(someData);
GET_VALUE_OR_RETURN(ResultType result, expect);
鉴于您实际上希望宏声明一个变量,使用它"不受保护的"在if
/ else
分支中不太可能;因此,缺失的do
- while
并不重要。
你甚至可以更进一步:
#define GET_VALUE_OR_RETURN(type, value, expect) \
auto &&value ## SuffixToPreventNameConflicts = (expect); \
if (!(value ## SuffixToPreventNameConflicts).valid()) return (value ## SuffixToPreventNameConflicts).get_error(); \
type value = move((value ## SuffixToPreventNameConflicts).get())
// Used like
GET_VALUE_OR_RETURN(ResultType, result, CreateInstance(someData));
或者更进一步,从参数中删除type
并在第二个声明中使用auto
。
请注意,SuffixToPreventNameConflicts
并不是占位符;它可以从字面上理解。由于变量的名称基于value
,因此宏的使用不会发生双重性(因为无论如何都会发生结果变量)。仅存在后缀以防止与同一范围内的其他无关变量发生意外冲突。