【问题标题】:dynamic_cast in assert Causing Error断言中的dynamic_cast导致错误
【发布时间】:2017-03-16 00:23:07
【问题描述】:

我使用的是过时的 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 world\n";

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

警告C4002:宏assert的实际参数过多
错误 C2143:语法错误:在 ')' 之前缺少 ','

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • Re: "answer below me" -- SO 根据各种因素重新排列答案,因此 "below" 和 "above" 可以改变。例如,现在,我在您的下方没有看到任何答案,但我确实在其上方看到了一个。
    • @PeteBecker 我花了 20 秒寻找正确的词,而 below 是我最后的选择......
    • @DeiDei 只需链接答案。
    【解决方案2】:

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

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

    或者,如果您愿意,可以用括号括住整个内容:

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

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

    【讨论】:

      猜你喜欢
      • 2020-10-19
      • 2023-03-03
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多