为什么这个宏接受带有1个参数的模板并拒绝带有2个参数的模板?

时间:2017-01-10 09:47:53

标签: c++ templates macros cppunit

我正在使用CPPUNIT 1.12.1。

它定义了那些宏:

#define CPPUNIT_TEST_SUITE_ADD_TEST( test ) \
      context.addTest( test )

#define CPPUNIT_TEST( testMethod )                        \
    CPPUNIT_TEST_SUITE_ADD_TEST(                           \
        ( new CPPUNIT_NS::TestCaller<TestFixtureType>(    \
                  context.getTestNameFor( #testMethod),   \
                  &TestFixtureType::testMethod,           \
                  context.makeFixture() ) ) )

我想使用模板向同一测试套件添加许多测试(因为CPPUNIT有效,每个测试必须是void函数,因此使用模板可以调用相同的void函数不同的“参数”......)。

这非常有效:

class MyTestSuite1 : public CPPUNIT_NS::TestFixture
{
    CPPUNIT_TEST_SUITE(MyTestSuite1);
    CPPUNIT_TEST(doTest<false>);
    CPPUNIT_TEST(doTest<true>);
    CPPUNIT_TEST_SUITE_END();

    template<bool param> void doTest() { /* test here */ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(MyTestSuite1);

虽然没有:

class MyTestSuite2 : public CPPUNIT_NS::TestFixture
{
    CPPUNIT_TEST_SUITE(MyTestSuite2);
    CPPUNIT_TEST(doTest<false,false>);
    CPPUNIT_TEST(doTest<true,false>);
    CPPUNIT_TEST_SUITE_END();

    template<bool param1,bool param2> void doTest() { /* test here */ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(MyTestSuite2);

编译器(Visual Studio 2015)报告:

  

1&GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(20):   警告C4002:宏'CPPUNIT_TEST'的实际参数太多   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(21):   警告C4002:宏'CPPUNIT_TEST'的实际参数太多   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(20):   错误C2059:语法错误:')'   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(21):   错误C2059:语法错误:')'   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(22):   错误C2143:语法错误:缺少';'之前'}'   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(22):   错误C2065:'namer':未声明的标识符   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(22):   错误C2065:'factory':未声明的标识符   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(22):   错误C2059:语法错误:')'   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(29):   错误C2143:语法错误:缺少';'在'{'之前   1 GT; B:\ dev的\ vobs_diabeloop \私人\ TST \调节\ CppUnit的\ hyper_ftac3 \ TEST.CPP(30):   错误C2143:语法错误:缺少';'在'{'

之前

为什么?宏如何正确处理1个模板参数,但两个失败?知道如何轻松编译和工作吗?

编辑: 已经尝试CPPUNIT_TEST((doTest<false,false>));但没有成功(获得error C2143: syntax error: missing ';' before ')'

3 个答案:

答案 0 :(得分:2)

doTest<false

这个没有用,因为宏认为你传递了两个宏参数:false>CPPUNIT_TEST((doTest<false,false>));

&TestFixtureType::testMethod

这不起作用,因为&TestFixtureType::(doTest<false,false>)会扩展为无效的#define COMMA , class MyTestSuite2 : public CPPUNIT_NS::TestFixture { CPPUNIT_TEST_SUITE(MyTestSuite2); CPPUNIT_TEST(doTest<false COMMA false>); CPPUNIT_TEST(doTest<true COMMA false>); CPPUNIT_TEST_SUITE_END(); template<bool param1, bool param2> void doTest() { /* test here */ } }; CPPUNIT_TEST_SUITE_REGISTRATION(MyTestSuite2);

正如Piotr在评论中所提到的,您可以使用以下代码:

smack chat library

因为预处理器发现您要传递1个参数

答案 1 :(得分:1)

,在MACRO中被解析为分隔符(除非由父项包围)。

解决方法

使用中间MACRO:

#define COMMA ,

CPPUNIT_TEST(doTest<false COMMA false>);

或修复原始MACRO以处理逗号:

#define CPPUNIT_TEST(testMethod, ...)                           \
    CPPUNIT_TEST_SUITE_ADD_TEST(                                \
        ( new CPPUNIT_NS::TestCaller<TestFixtureType>(          \
                  context.getTestNameFor( #testMethod),         \
                  &TestFixtureType::testMethod , ##__VA_ARGS__, \
                  context.makeFixture() ) ) )

答案 2 :(得分:0)

这有用吗?

{{1}}

有时在解析逗号时,宏可能会很棘手......