断言中的dynamic_cast导致错误

时间:2016-11-02 15:49:25

标签: c++ visual-studio gcc assert dynamic-cast

我使用过时的Visual Studio 2008(让我省去麻烦"那是你的问题"。)这似乎是Visual Studio的一个问题: http://rextester.com/XKFR77690 这似乎是ViewGroup宏的一个问题:http://ideone.com/bhxMi0

鉴于这些结构:

assert

我可以这样做:

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"; 中的if语句完全相同的代码时,我会收到错误:

  

警告C4002:宏assert的实际参数太多了   错误C2143:语法错误:缺少&#39;,&#39;之前&#39;)&#39;

顺便说一句,我可以通过使用C风格的演员来解决这个问题:assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL)但是我觉得C风格的演员会做assert而不是assert((Foo<pair<int, int>>*)(test) != NULL)我不会这样做;想要。

2 个答案:

答案 0 :(得分:9)

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附近也可以完成这项工作。

答案 1 :(得分:9)

Yup:宏将顶级逗号视为参数分隔符。最简单的解决方法是将括号放在有问题的代码周围:

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

或者,如果您愿意,可以围绕整个内容括起来:

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

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