dynamic_cast在assert中导致错误

dynamic_cast in assert Causing Error

本文关键字:错误 assert cast dynamic      更新时间:2023-10-16

我使用的是过时的Visual Studio 2008(让我为您省去麻烦"这就是您的问题")。这似乎是一个问题与Visual Studio: http://rextester.com/XKFR77690这似乎是一个问题与assert宏: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 worldn";

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

警告C4002:宏assert的实际参数太多
语法错误:缺少',' before ')'

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

是的:宏将顶级逗号视为参数分隔符。最简单的修复方法是在问题代码周围加上括号:

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

或者,如果你喜欢,在整个内容周围加上括号:

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

问题中的c风格强制转换编译的原因不是它是c风格强制转换,而是它将模板代码放在括号中,因此逗号不再位于最外层。

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周围也可以。