dynamic_cast 在断言中导致错误

dynamic_cast in assert Causing Error

我使用的是过时的 Visual Studio 2008(让我为您省去麻烦 "there's your problem"。)这似乎是 Visual Studio 的问题:http://rextester.com/XKFR77690 This seems to be a problem with the assert macro: http://ideone.com/bhxMi0

鉴于这些结构:

struct base { virtual ~base() {} };

template <typename T>
struct Foo : base { T foo; };

我能做到:

base* test = new Foo<pair<int, int>>;

if(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) cout << "hello world\n";

但是当我使用与 assert 中的 if 语句完全相同的代码时:assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) 我得到一个错误:

warning C4002: too many actual parameters for macro assert
error C2143: syntax error : missing ',' before ')'

顺便说一句,我可以通过使用 C 风格的转换来解决这个问题:assert((Foo<pair<int, int>>*)(test) != NULL) 但我认为 C 风格的转换会做 static_cast 而不是 dynamic_cast 我不知道不想。

assert 是一个宏。它由对 C++ 构造一无所知的预处理器处理。所以如下:

assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL)

扩展为带有两个参数的类似函数的宏,在本例中为:

dynamic_cast<Foo<pair<int

int>>*>(test) != NULL

请记住,类似函数的宏参数用逗号分隔。这就是预处理器看到的所有内容。所以在这种情况下,它看到 2 个参数而不是 assert.

所需的 1 个参数

由于括号的优先级高于逗号,您的 C 风格强制转换版本可以正常工作。将它们放在 dynamic_cast 周围也可以完成这项工作。

是的:宏将顶级逗号视为参数分隔符。最简单的解决方法是在有问题的代码两边加上括号:

assert((dynamic_cast<Foo<pair<int, int>>*>(test)) != NULL)

或者,如果您愿意,将整个内容括起来:

assert((dynamic_cast<Foo<pair<int, int>>*>(test) != NULL))

问题中的C-style cast编译通过的原因不是它是C-style cast,而是将模板代码放在括号中,因此逗号不再位于最外层。