允许赋值或存在当前函数的宏

时间:2015-03-27 14:58:00

标签: c++ c-preprocessor

我希望能够实现:

#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行代码才能使用有效值初始化我的变量。还有更好的东西吗?

1 个答案:

答案 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,因此宏的使用不会发生双重性(因为无论如何都会发生结果变量)。仅存在后缀以防止与同一范围内的其他无关变量发生意外冲突。