【问题标题】:Custom iterator which converts values before saving it自定义迭代器,在保存之前转换值
【发布时间】:2010-05-19 08:55:54
【问题描述】:

一个典型的前向迭代器应该实现以下方法:

value_type& operator*();
value_type* operator->();

我正在为自定义容器编写自定义迭代器,用户希望看到value_type 与容器内的值表示不同。因此,当将value_type 值返回给用户时,我将其从内部表示转换为用户预期的value_type。在提到的成员内部很容易实现。

您能建议如何处理左值吗?当用户以 *it = value_type(5) 之类的语法将值分配给迭代器时,我在哪里可以处理 value_type 到内部表示的转换?

我想过返回一个仿函数,但我不喜欢这个想法,因为调用方的语法不寻常。

【问题讨论】:

    标签: c++ iterator


    【解决方案1】:

    如果你要返回一个引用,那么你不能转换并返回一个引用,除非你存储转换后的值,此时我开始质疑内部表示的观点。我不确定你想要的是否可能。这方面的一个例子是vector<bool>,这是传说中的,因为它不能正常工作。如果标准委员会不能使这样的容器工作,那可能不是一个好主意。

    【讨论】:

      【解决方案2】:

      您可能想看看std::vector<bool> 特化迭代器的实现,因为它们解决了同样的问题。请注意,随着时间的推移,专业化已不受欢迎,主要是因为它不符合容器要求(迭代器不提供对实际包含类型的引用,而是提供代理值),这也将成为您的问题实施。

      另一种可能的方法是使用常规容器,但让存储的类型接受实现与用户预期类型之间的分配/转换。如果您当前的存储类型无法做到这一点,您可以为其编写一个包装器。

      一个简化的包装器(您需要对其进行处理才能使其工作):

      template <typename T, typename U>
      class wrapper
      {
      public:
         typedef T store_type;
         typedef U value_type;
         wrapper() : stored() {}
         wrapper( value_type const & v ) 
            : stored( convert<store_type>(v) {}
         wrapper& operator=( value_type const & value ) { // or pass-by-value
            stored = convert<store_type>(value); // or however you can convert them
            return *this;
         }
         operator value_type() const { // I don't quite like this, if possible use explicit conversions
            return convert<value_type>(stored);
         }
      private:
         store_type stored; // maybe storage is handled externally and this can be pointer/ref.
      };
      // For the simple test double<->int conversion static cast suffices
      template <typename T, typename U>
      T convert( U in ) {
         return static_cast<T>(in); 
      }
      int main() {
         std::vector< wrapper<double,int> > v;
         v.push_back( 10 );
         int x = v[0];
         v[0] = 5;
      
         std::vector< wrapper<int,double> > v2;
         v.push_back( 10.5 );
         double y = v2[0];
         v2[0] = 11.3;
      }
      

      【讨论】:

      • 您能否提供一个使用这种包装器的示例?方法会是什么样子?
      • 你有其他关于接口类型和商店类型的信息吗?
      • 只需value_type 和stored_type。它是一个模板参数。通常stored_type 是int*。还有一个Wrapper 成员value_type operator() (strored_type s) 和stored_type operator() (value_type v),但可以添加任何其他成员。
      猜你喜欢
      • 2016-04-05
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 2021-02-13
      • 2020-01-03
      • 2013-05-21
      • 2015-02-04
      相关资源
      最近更新 更多