将模板参数传递给 MSVC 中的宏
Posted
技术标签:
【中文标题】将模板参数传递给 MSVC 中的宏【英文标题】:Passing template parameters into macros in MSVC 【发布时间】:2017-01-31 16:51:49 【问题描述】:我正在尝试在最初在 Linux 上开发的 Visual Studio 2017 中编译 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) \
<< "\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 必须有一些特别之处,即我所缺少的宏的使用方式。根据我的研究,应该正确处理重载的宏,所以我不明白为什么会出现这些错误。
【问题讨论】:
【参考方案1】:这里的主要问题是 MSVC 在宏扩展内的宏调用中处理 __VA_ARGS__
的方式。请参阅this question 和答案,其中包括 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。
【讨论】:
以上是关于将模板参数传递给 MSVC 中的宏的主要内容,如果未能解决你的问题,请参考以下文章