将模板参数传递到 MSVC 中的宏中

Passing template parameters into macros in MSVC

本文关键字:MSVC 参数传递      更新时间:2023-10-16

我正在尝试在Visual Studio 2017中编译最初在Linux上开发的C++代码。 该项目在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) 
<< "nnValue of " #actual " [" << (actual).rows() << " x " << (actual).cols() << "]:n" 
<< (actual)   
<< "nn"

错误:

C:UsersANTadminDesktopscorpion-cpptestincludeLinearFilterTests.h(19): warning C4003: not enough actual parameters for macro 'NAVUTILS_TEST_MATRIX_EQUAL_' 
C:UsersANTadminDesktopscorpion-cpptestincludeLinearFilterTests.h(19): error C2059: syntax error: ')' 
C:UsersANTadminDesktopscorpion-cpptestincludeLinearFilterTests.h(19): error C2181: illegal else without matching if 
C:UsersANTadminDesktopscorpion-cpptestincludeLinearFilterTests.h(19): error C2065: 'gtest_ar_': undeclared identifier 
C:UsersANTadminDesktopscorpion-cpptestincludeLinearFilterTests.h(19): error C2228: left of '.c_str' must have class/struct/union 
C:UsersANTadminDesktopscorpion-cpptestincludeLinearFilterTests.h(19): error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'testing::internal::AssertHelper' 
C:UsersANTadminDesktopscorpion-cpptestincludeLinearFilterTests.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 中有效。