c++ - 将模板参数传递给 MSVC 中的宏

标签 c++ visual-studio macros visual-studio-2017 variadic-macros

我正在尝试在 Visual Studio 2017 中编译最初在 Linux 上开发的 C++ 代码。该项目按原样在 Linux 上编译,但不在 VS 上编译。错误来自尝试使用宏来比较模板参数。

调用:

EXPECT_MATRIX_EQUAL(filter.xhat, mat);

其中 'filter.xhat' 和 'mat' 都是 vector

定义:

#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__ 的方式。参见 this question以及包含微软关于标准解释的声明的答案。正如该问题的公认答案所建议的那样,解决方案是一个额外的间接级别:

#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。

关于c++ - 将模板参数传递给 MSVC 中的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41963063/

相关文章:

c++ - C++ 中的多重定义错误,即使我没有包含多个文件

c++ - Qt - 像素操作后显示无符号字符

c++ - 在嵌入式 x86 程序集中添加数组?

c# - 如何同时使用两个控制台应用程序调试 WCF 服务

C++宏展开、调试

c++ - 何时使用虚拟析构函数?

c++ - 我如何将 std::get 作为参数传递给模板函数?

c++ - 如何在 Visual Studio 2012 中用 C++11 替换所有 BOOST_FOREACH?

c - 如何检查参数是否是 C 预处理器宏中的整型常量表达式?

c - 宏和函数定义的不同输出