【问题标题】:Length between iterators in size_typesize_type 中迭代器之间的长度
【发布时间】:2018-09-11 14:40:15
【问题描述】:

我正在编写自定义算法,在某些时候它需要获取两个迭代器之间的距离。如果我假设 it1 it2 我可以得到它们之间的正距离(it2 - it1)。这没关系,但是std::distanceoperator- 返回difference_type(在我的情况下)是long long 的别名。如果距离太大而无法放入long long 但可以放入unsigned long long(在我的情况下是size_type 别名)怎么办? 对于这个例子,我还假设long longint64_tunsigned long longuint64_t

std::string container = ...; // assume enourmous number of characters, like 2^64 - 1024
std::cout << (container.begin() - container.end());

由于operator- 返回difference_type,它不适合2^64 - 1024,由于溢出,它应该打印负数(实际上是任何东西-它是UB)。当然,我可以将其转换回std::string::size_type,但我不能确定以前的未定义行为是否像我假设的那样有效。我该如何处理这样的问题?

【问题讨论】:

  • 您不能将距离存储在difference_type 类型的变量中吗?我的意思是您可以使用基于模板的解决方案来涵盖所有情况。
  • 在我不那么谦虚的意见中,如果你有这么大的数据集,你需要一个无符号的 64 位整数来表示两个元素之间的“距离”,那么你使用了错误的数据结构或错误的设计。
  • 并不是我会有这么多数据。我只想知道可能的解决方案是什么。我不希望我的算法在“大多数情况下”起作用。我可以使用转换保留它,但数据溢出是可行的:/
  • 2^64 内存的成本是多少,您的任何客户能否将其专用于您程序中的单个容器?
  • 这个问题真的很简单,如果你有C++11编译器的话。只需使用auto :)

标签: c++ iterator difference size-type


【解决方案1】:

[..] 如果距离太大而无法放入 [distance_type] 但可以放入 [其他类型] [..]

我该如何处理这样的问题?

你不能。这是实现容器以及相应迭代器的人的工作。

如果他们用于距离的类型不能适合容器可能出现的所有值,那么这是容器中的错误。

澄清:difference_type 实际上是使用了depends on the iterators

【讨论】:

    【解决方案2】:

    关于我将如何解决问题的可能实现。

    让我们把它留给类型推断系统来做出正确的调用。

    C++11 前的实现 -

    template<typename It>
    void distance_algo_impl(It const & begin, It const & end)
    {
        typename std::iterator_traits<It>::difference_type distance
            = std::distance(begin, end);
    
        std::cout << "\ndistance :" << distance << "\n";
        // ... do your distance based algorithm here
    }
    
    template<typename T>
    void distance_algo(T const & container)
    {
        distance_algo_impl(container.begin(), container.end());
    }
    

    后 C++11 实现 -

    template<typename T>
    void distance_algo(T const & container)
    {
        auto distance = std::distance(container.begin(), container.end());
        std::cout << "\ndistance :" << distance << "\n";
        // ... do your distance based algorithm here
    }
    

    【讨论】:

    • 这不是我想要的。我知道类型推导可以“起作用”,但这并不能解决转换有符号->无符号的问题。
    • 嗯,我不清楚你想要什么。如果您需要unsigned 数据类型的容量,以及签名数据类型的灵活性,我建议您创建自己的新类型。一种新类型,它将是一对 &lt;bool, unsigned&gt; 。如果您愿意,我可以绘制一个适用于新数据类型的示例应用程序。 bool 将存储符号信息,而 unsigned 部分将存储幅度。
    【解决方案3】:

    这永远不会成为问题。我们知道这一点是因为max_size 表示为size_tmax_size的返回代表:

    由于系统或库实现限制,string 能够容纳的最大元素数,即std::distance(begin(), end()) 表示最大字符串

    因此,无法使用大于size_t 分隔的string 的迭代器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-06
      • 1970-01-01
      • 2021-11-27
      • 2013-09-10
      • 2016-01-02
      • 2013-04-05
      • 1970-01-01
      • 2010-12-04
      相关资源
      最近更新 更多