Why does this macro accept a template with 1 parameter and refuse a template with two parameters?

I work with CPPUNIT 1.12.1.

It has the following macros:

#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() ) ) ) 

I want to add many tests to the same test suite using templates (how CPPUNIT works, each test should be a void function, so using a template allows you to call the same void function with different "parameters", ...).

This works great:

 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); 

while it is not:

 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); 

Compiler Reports (Visual Studio 2015):

1> b: \ DEV \ vobs_diabeloop \ private \ TST \ regulation \ CppUnit \ hyper_ftac3 \ test.cpp (20): warning C4002: too many actual parameters for the macro "CPPUNIT_TEST" 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ throttling \ CppUnit \ hyper_ftac3 \ test.cpp (21): warning C4002: too many actual parameters for the macro "CPPUNIT_TEST" 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ throttling \ CppUnit \ hyper_ftac3 \ test.cpp (20 ): error C2059: syntax error: ')' 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ regulation \ CppUnit \ hyper_ftac3 \ test.cpp (21): error C2059: syntax error: ')' 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ regulation \ CppUnit \ hyper_ftac3 \ test.cpp (22): error C2143: syntax I error: missing ';' before '}' 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ regulation \ CppUnit \ hyper_ftac3 \ test.cpp (22): error C2065: 'namer': undeclared identifier 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ throttling \ CppUnit \ hyper_ftac3 \ test.cpp (22): error C2065: 'factory': undeclared identifier 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ throttling \ CppUnit \ hyper_ftac3 \ test.cpp (22): error C2059: syntax error: ')' 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ regulation \ CppUnit \ hyper_ftac3 \ test.cpp (29): error C2143: syntax error: missing ';' before '{' 1> b: \ DEV \ vobs_diabeloop \ private \ TST \ regulation \ CppUnit \ hyper_ftac3 \ test.cpp (30): error C2143: syntax error: missing ';' before '{'

Why? How can a macro correctly handle 1 template parameter, but cannot execute two? Any idea how I could easily compile and work it?

Edit: Already tried CPPUNIT_TEST((doTest<false,false>)); without success (getting error C2143: syntax error: missing ';' before ')' )

0
c ++ macros templates cppunit
source share
3 answers
 CPPUNIT_TEST(doTest<false,false>); 

This does not work because the macro thinks you are passing 2 macro parameters: doTest<false and false> .


 CPPUNIT_TEST((doTest<false,false>)); 

This does not work because &TestFixtureType::testMethod will expand to &TestFixtureType::(doTest<false,false>) , which is not valid.


As mentioned in the Piotr comment, you can use this code:

 #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); 

Since the pre-processor sees that you want to pass 1 parameter

+2
source share

, parsed as a delimiter in MACRO (unless it is surrounded by a parent).

workaround

using intermediate MACRO:

 #define COMMA , CPPUNIT_TEST(doTest<false COMMA false>); 

Or fix your original MACRO to handle the comma:

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

does it work

 CPPUNIT_TEST((doTest<false,false>)); CPPUNIT_TEST((doTest<true,false>)); 

Sometimes macros can be tricky to parse commas ...

0
source share

All Articles