我使用过时的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)
我不会这样做;想要。
答案 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风格的转换,而是它将模板代码放在括号中,因此逗号不再位于最外层。