2017-01-10 1 views
0

Я работаю с CPPUNIT 1.12.1.Почему этот макрос принимает шаблон с 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>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(20): warning C4002: too many actual parameters for macro 'CPPUNIT_TEST' 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(21): warning C4002: too many actual parameters for macro 'CPPUNIT_TEST' 1>b:\dev\vobs_diabeloop\private\tst\regulation\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 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\regulation\cppunit\hyper_ftac3\test.cpp(22): error C2065: 'factory': undeclared identifier 1>b:\dev\vobs_diabeloop\private\tst\regulation\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 '{'

Почему это? Как макрос может корректно обрабатывать 1 параметр шаблона, но не удается выполнить два? Любая идея, как я мог легко ее скомпилировать и работать?

Edit: Уже пытались CPPUNIT_TEST((doTest<false,false>)); без успеха (получение error C2143: syntax error: missing ';' before ')')

+4

'#define запятой,' 'то CPPUNIT_TEST (doTest ); ' –

+0

@PiotrSkotnicki: Невероятно ... это работает. Но мне очень любопытно понять, почему ...не могли бы вы опубликовать это как ответ с большим количеством объяснений? – jpo38

+0

'CPPUNIT_TEST ((doTest ));' -> '& TestFixtureType: :(doTest )' недействителен. Препроцессор думает 'CPPUNIT_TEST (doTest );' имеет 1 параметр – Danh

ответ

2
CPPUNIT_TEST(doTest<false,false>); 

Это одна не работает, потому что макрос считает, что вы передаете 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); 

Поскольку препроцессор видит, что вы хотите передать 1 Параметр

+0

Хорошее объяснение. Спасибо, дан. – jpo38

0

делает эту работу?

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

иногда Макросы может быть сложно при разборе запятые ...

+0

Извините, должен был упомянуть об этом в моем сообщении. Уже пробовал без успеха. – jpo38

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()))) 
Смежные вопросы