在MACRO中使用构造函数

时间:2014-09-24 16:49:54

标签: c++ templates macros constructor

我遇到了一个我无法理解的错误。我在头文件中有一个如下所示的定义:

#define ASSERT_THROWS(exception_type,command) do {\
  try { \
    (command); \
    FAIL(std::string("Expected exception of type ") + #exception_type); \
  } catch (AssertionError&) { \
    throw; \
  } catch (exception_type&) { \
    \
  } catch (std::exception& e) { \
    FAIL(std::string("Expected exception of type ") + #exception_type + \
        ", but caught" + e.what()); \
  } catch (...) { \
    FAIL(std::string("Expected exception of type ") + #exception_type + \
        ", but caught an unknown object"); \
  } \
} while (0)

main看起来像这样:

ASSERT_THROWS(TqIllegalGradeException, (TQ<In,Out,TESO<In,Out> > tqS(101)));

我收到以下错误: expected primary-expression before 'tqS'expected ')' before 'tqS'。谁能解释一下是什么问题?从宏定义中删除括号没有帮助

1 个答案:

答案 0 :(得分:0)

宏用括号括起其参数以形成第一个语句。如果参数是一个表达式(如名称exp所暗示的那样),这是很好的,但如果它是一个声明则不行,因为语法不允许你在声明周围加上括号。

从宏定义中删除括号,或者不要尝试将其用于声明。

另外,如果您希望第二行打印表达式本身而不是字符串"exp",那么您希望将其字符串化而不是将其放在引号中:

std::cout << #exp << std::endl;

更新在新代码中,您有两组括号:

(command);
^       ^

ASSERT_THROWS(TqIllegalGradeException, (TQ<In,Out,TESO<In,Out> > tqS(101)));    
                                       ^                                 ^
如果您想允许command成为声明,则需要删除这两者。不幸的是,从宏调用中删除括号会破坏预处理器,因为它不会将<>识别为括号;你可能需要不那么雄心勃勃的宏用法:

typedef TQ<In,Out,TESO<In,Out> > Thingy;
ASSERT_THROWS(TqIllegalGradeException, Thingy tqS(101));

最后,如果你不能从宏中删除括号,也许你可以用一个以相同方式构造临时表达式的表达式替换声明:

ASSERT_THROWS(TqIllegalGradeException, (TQ<In,Out,TESO<In,Out> >(101)));