0

원래 Linux에서 개발 된 Visual Studio 2017에서 C++ 코드를 컴파일하려고합니다. 프로젝트는 Linux에서는 컴파일되지만 VS에서는 컴파일되지 않습니다. 매크로를 사용하여 템플릿 매개 변수를 비교하려고하면 오류가 발생합니다.MSVC의 매크로에 템플릿 매개 변수 전달

전화 : 'filter.xhat'과 '매트'두 벡터

있습니다

EXPECT_MATRIX_EQUAL(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 

특별한 무언가가있을 거라는 가정하에. i MSVC에서 매크로가 사용되는 방식이 빠졌습니다. 내가 왜 이러한 오류가 발생하는지 이해할 수 없기 때문에 오버로드 된 매크로를 제대로 조사해야합니다.

답변

1

여기서 중요한 문제는 MSVC가 매크로 확장 내에서 매크로 호출로 __VA_ARGS__을 처리하는 방식입니다. this question 및 표준 해석에 대한 Microsoft의 진술이 포함 된 답변을 참조하십시오.

__matrices_equal(expected, actual, ##__VA_ARGS__), \ 

##의 사용은 이전을 포함하지 않도록한다 :

#define EXPAND_(X) X 
#define EXPECT_MATRIX_EQUAL(...) \ 
EXPAND_(NAVUTILS_TEST_MATRIX_EQUAL_(GTEST_NONFATAL_FAILURE_, __VA_ARGS__)) 

는 또 다른 문제가있다 :이 솔루션은 그 질문에 대한 허용 대답에 제안, 간접의 추가 수준 ,__VA_ARGS__이 비어있는 경우 GCC 확장이며 이식 가능한 코드에 사용하면 안됩니다. 그러나 분명히 그것은 MSVC에서 작동합니다.