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,而是将模板代码放在括号中,因此逗号不再位于最外层。
我使用的是过时的 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
.
由于括号的优先级高于逗号,您的 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,而是将模板代码放在括号中,因此逗号不再位于最外层。