【问题标题】:Can I apply downcast to an iterator?我可以将向下转换应用于迭代器吗?
【发布时间】:2021-04-16 18:59:49
【问题描述】:

我需要知道我是否通过应用向下转换来向模板类发送正确类型的容器。

// C++ program to demonstrate input iterator
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
    vector<int> v1 = { 1, 2, 3, 4, 5 };

    // Declaring an iterator
    vector<int>::iterator i1;
    bidirectional_iterator & bi = dynamic_cast<i1&>(i1);
    if(bi != nullptr)
      cout << "Succesfull" << endl;
    for (i1 = v1.begin(); i1 != v1.end(); ++i1) {
        // Accessing elements using iterator
        cout << (*i1) << " ";
    }
    return 0;
}

我得到错误:

prog.cpp: In function ‘int main()’:
prog.cpp:12:2: error: ‘bidirectional_iterator’ was not declared in this scope
  bidirectional_iterator & bi = dynamic_cast<i1&>(i1);
  ^
prog.cpp:12:27: error: ‘bi’ was not declared in this scope
  bidirectional_iterator & bi = dynamic_cast<i1&>(i1);
                           ^
prog.cpp:12:45: error: ‘i1’ does not name a type
  bidirectional_iterator & bi = dynamic_cast<i1&>(i1);
                                             ^
prog.cpp:12:47: error: expected ‘>’ before ‘&’ token
  bidirectional_iterator & bi = dynamic_cast<i1&>(i1);
                                               ^
prog.cpp:12:47: error: expected ‘(’ before ‘&’ token
prog.cpp:12:48: error: expected primary-expression before ‘>’ token
  bidirectional_iterator & bi = dynamic_cast<i1&>(i1);
                                                ^
prog.cpp:12:53: error: expected ‘)’ before ‘;’ token
  bidirectional_iterator & bi = dynamic_cast<i1&>(i1);

我是否可以检查容器中迭代器的类型,以便控制它是否会在模板类中传递?

【问题讨论】:

  • 看起来你正在使用变量作为类型dynamic_cast&lt;i1&amp;&gt;进行转换
  • 您不应将迭代器与nullptr 进行比较。它没有意义,通常它甚至不会编译。此外,dynamic_cast&lt;T&amp;&gt; 将在失败时抛出 std::bad_cast。如果您正在投射指针,您应该只使用nullptr 比较来检查dynamic_cast 是否成功。 dynamic_cast&lt;T*&gt; 在失败时返回 nullptr 而不是抛出。
  • 您可以像使用双向迭代器一样使用迭代器,否则模板实例化将失败。如果它像鸭子一样走路,像鸭子一样嘎嘎叫,那就是鸭子
  • @NathanOliver 是的。这绝对是我需要的。感谢您的建议。

标签: c++ stl iterator polymorphism downcast


【解决方案1】:

dynamic_cast 对实例化的对象执行运行时检查。

模板解析(主要)适用于类型(不是对象),并且发生在编译时。一个类型的编译时检查的例子是std::is_base_of&lt;Base,Type&gt;

vector<int>::iterator i1;

using iterator_type = std::iterator_traits<decltype(i1)>::iterator_category;
if( std::is_base_of_v<std::bidirectional_iterator_tag,iterator_type> )
// Can be "if constexpr" above, since this is known at compile time
{
  cout << "Succesfull" << endl;

【讨论】:

  • 我想我明白了。这对我来说是非常陌生的概念。但我明白了。我会试试这个方法。谢谢。
【解决方案2】:

看起来您完全误解了标准库中的迭代器。首先,如果您发现自己使用任何标准库类型执行dynamic_cast(一个值得注意的例外 - 他,双关语 - 是std::exception,也许还有一些我现在没有想到的其他类型)你做错了什么。绝大多数 STL 类型都不是多态的,不应该这样使用。

迭代器也是如此。您不需要将std::vector::iterator 转换为biderectional_iterator,而只需在需要此类迭代器的地方使用它。有iterator_traits,当与向量迭代器一起使用时,将指示向量的迭代器通过iterator_category 是双向的。查看iterator_traits的更多信息

trait 的美妙之处在于所有这些逻辑都是在编译时完成的,所以如果你试图在迭代器中使用它无法处理的场景,你最终会出现编译错误,并且可以立即修复程序.

【讨论】:

  • 这很好解释谢谢你的回答。
猜你喜欢
  • 2011-01-03
  • 1970-01-01
  • 2020-10-28
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多