Jon*_*Mee 11 c++ gcc assert dynamic-cast visual-studio
我正在使用过时的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; };
Run Code Online (Sandbox Code Playgroud)
我可以做这个:
base* test = new Foo<pair<int, int>>;
if(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) cout << "hello world\n";
Run Code Online (Sandbox Code Playgroud)
但是当我在if-statement中使用完全相同的代码时assert:assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL)我得到一个错误:
警告C4002:宏
assert
错误C2143的实际参数太多:语法错误:缺少','之前')'
顺便说一句,我可以通过使用C风格的演员来解决这个问题:assert((Foo<pair<int, int>>*)(test) != NULL)但我认为C风格演员阵容static_cast不是dynamic_cast我不想要的.
assert是一个宏.它由预处理器处理,它对C++构造一无所知.所以以下内容:
assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL)
Run Code Online (Sandbox Code Playgroud)
扩展为一个类似函数的宏,它带有两个参数,在本例中是:
dynamic_cast<Foo<pair<int
Run Code Online (Sandbox Code Playgroud)
和
int>>*>(test) != NULL
Run Code Online (Sandbox Code Playgroud)
请记住,类似函数的宏参数用逗号分隔.这就是预处理器看到的全部内容.所以在这种情况下,它会看到2个参数而不是所需的1个参数assert.
由于括号的优先级高于逗号,因此C风格的强制转换版本可以顺带使用.将它们放在一起dynamic_cast也可以完成工作.
是的:宏将顶级逗号视为参数分隔符.最简单的解决方法是在有问题的代码周围添加括号:
assert((dynamic_cast<Foo<pair<int, int>>*>(test)) != NULL)
Run Code Online (Sandbox Code Playgroud)
或者,如果您愿意,可以围绕整个内容括起来:
assert((dynamic_cast<Foo<pair<int, int>>*>(test) != NULL))
Run Code Online (Sandbox Code Playgroud)
问题中的C风格转换编译的原因并不是它是C风格的转换,而是它将模板代码放在括号中,因此逗号不再处于最外层.