Я пытаюсь скомпилировать код C ++ в Visual Studio 2017, который изначально был разработан для Linux. Проект как есть компилируется в Linux, но не в VS. Ошибки возникают из-за попытки использовать макрос для сравнения параметров шаблона.
Вызов:
EXPECT_MATRIX_EQUAL(filter.xhat, mat);
Где «filter.xhat» и «mat» оба вектора
Определяет:
#define EXPECT_MATRIX_EQUAL(...) \
NAVUTILS_TEST_MATRIX_EQUAL_(GTEST_NONFATAL_FAILURE_, __VA_ARGS__)
#define NAVUTILS_TEST_MATRIX_EQUAL_(fail, expected, actual, ...) \
NAVUTILS_TEST_EQUAL_(expected, \
actual, \
__matrices_equal(expected, actual, ##__VA_ARGS__), \
fail)
#define NAVUTILS_TEST_EQUAL_(expected, actual, testExpr, fail) \
GTEST_TEST_BOOLEAN_(testExpr, #testExpr, actual, expected, fail) \
<< "Value of " #expected " [" << (expected).rows() << " x " << (expected).cols() << "]:\n" \
<< (expected) \
<< "\n\nValue of " #actual " [" << (actual).rows() << " x " << (actual).cols() << "]:\n" \
<< (actual) \
<< "\n\n"
Ошибки:
C:\Users\ANTadmin\Desktop\scorpion-cpp\test\include\LinearFilterTests.h(19): warning C4003: not enough actual parameters for macro 'NAVUTILS_TEST_MATRIX_EQUAL_'
C:\Users\ANTadmin\Desktop\scorpion-cpp\test\include\LinearFilterTests.h(19): error C2059: syntax error: ')'
C:\Users\ANTadmin\Desktop\scorpion-cpp\test\include\LinearFilterTests.h(19): error C2181: illegal else without matching if
C:\Users\ANTadmin\Desktop\scorpion-cpp\test\include\LinearFilterTests.h(19): error C2065: 'gtest_ar_': undeclared identifier
C:\Users\ANTadmin\Desktop\scorpion-cpp\test\include\LinearFilterTests.h(19): error C2228: left of '.c_str' must have class/struct/union
C:\Users\ANTadmin\Desktop\scorpion-cpp\test\include\LinearFilterTests.h(19): error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'testing::internal::AssertHelper'
C:\Users\ANTadmin\Desktop\scorpion-cpp\test\include\LinearFilterTests.h(19): note: No constructor could take the source type, or constructor overload resolution was ambiguous
Я предполагаю, что в MSVC должно быть что-то особенное с тем, как используются макросы, которые я пропускаю. Из того, что я исследовал, перегруженные макросы должны обрабатываться правильно, поэтому я не понимаю, почему я получаю эти ошибки.
Основным вопросом здесь является способ работы MSVC __VA_ARGS__
в вызове макроса внутри раскрытия макроса. Увидеть этот вопрос и ответ, который включает заявление Microsoft о толковании стандарта. Решение, как предлагается в принятом ответе на этот вопрос, заключается в дополнительном уровне косвенности:
#define EXPAND_(X) X
#define EXPECT_MATRIX_EQUAL(...) \
EXPAND_(NAVUTILS_TEST_MATRIX_EQUAL_(GTEST_NONFATAL_FAILURE_, __VA_ARGS__))
Есть еще одна проблема:
__matrices_equal(expected, actual, ##__VA_ARGS__), \
Что использование ##
избегать включения предыдущего , если __VA_ARGS__
пусто является расширением GCC и не должно использоваться в переносимом коде. Однако, видимо, это работает в MSVC.
Других решений пока нет …