C++ 在保存之前转换值的自定义迭代器

C++ 在保存之前转换值的自定义迭代器,c++,iterator,C++,Iterator,典型的前向迭代器应实现以下方法: value_type& operator*(); value_type* operator->(); 我正在为一个自定义容器编写一个自定义迭代器,用户希望看到一个与容器中的值表示不同的value\u类型。因此,当向用户返回值类型值时,我将其从内部表示转换为用户期望的值类型。在上述成员中很容易实现 你能建议如何处理l值吗?当用户以类似于*it=value\u type(5)的语法将值分配给迭代器时,我在哪里可以处理value\u type到内部表示

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

value_type& operator*();
value_type* operator->();
我正在为一个自定义容器编写一个自定义迭代器,用户希望看到一个与容器中的值表示不同的
value\u类型。因此,当向用户返回
值类型
值时,我将其从内部表示转换为用户期望的
值类型
。在上述成员中很容易实现

你能建议如何处理l值吗?当用户以类似于
*it=value\u type(5)
的语法将值分配给迭代器时,我在哪里可以处理
value\u type
到内部表示的转换


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

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

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

您可能需要研究一下std::vector专门化迭代器的实现,因为它们处理相同的问题。请注意,随着时间的推移,专门化一直受到反对,主要是因为它不符合容器要求(迭代器不提供对实际包含类型的引用,而是提供一个代理值),这也是实现中的一个问题

另一种可能的方法是使用常规容器,但让存储的类型accept实现与用户期望的类型之间的赋值/转换。如果当前存储的类型不可能这样做,则可以为其编写包装器

一个简化的包装器(您需要使用它才能使其正常工作):

模板
类包装器
{
公众:
类型定义T存储类型;
类型定义U值\ U类型;
包装器():存储的(){}
包装器(值\类型常量和v)
:存储(转换(v){}
包装器和运算符=(值\类型常量和值){//或按值传递
stored=convert(value);//或者您可以如何转换它们
归还*这个;
}
运算符value_type()const{//我不太喜欢这样,如果可能的话,可以使用显式转换
返回转换(存储);
}
私人:
store_type stored;//可能存储是在外部处理的,这可以是指针/ref。
};
//对于简单的测试,双精度转换静态转换就足够了
模板
T转换(U英寸){
返回静态_-cast(in);
}
int main(){
std::vectorv;
v、 推回(10);
int x=v[0];
v[0]=5;
std::vectorv2;
v、 推回(10.5);
双y=v2[0];
v2[0]=11.3;
}

您可能需要研究一下
std::vector
专门化迭代器的实现,因为它们解决了相同的问题。请注意,随着时间的推移,专门化一直受到反对,主要是因为它不符合容器要求(迭代器不提供对实际包含类型的引用,而是提供一个代理值),这也是实现中的一个问题

另一种可能的方法是使用常规容器,但让存储类型accept实现与用户期望的类型之间的赋值/转换。如果当前存储类型不可能这样做,则可以为其编写包装器

一个简化的包装器(您需要使用它才能使其正常工作):

模板
类包装器
{
公众:
类型定义T存储类型;
类型定义U值\ U类型;
包装器():存储的(){}
包装器(值\类型常量和v)
:存储(转换(v){}
包装器和运算符=(值\类型常量和值){//或按值传递
stored=convert(value);//或者您可以如何转换它们
归还*这个;
}
运算符value_type()const{//我不太喜欢这样,如果可能的话,可以使用显式转换
返回转换(存储);
}
私人:
store_type stored;//可能存储是在外部处理的,这可以是指针/ref。
};
//对于简单的测试,双精度转换静态转换就足够了
模板
T转换(U英寸){
返回静态_-cast(in);
}
int main(){
std::vectorv;
v、 推回(10);
int x=v[0];
v[0]=5;
std::vectorv2;
v、 推回(10.5);
双y=v2[0];
v2[0]=11.3;
}

你能提供一个使用这种包装器的示例吗?方法会是什么样子?你有关于接口类型和存储类型的其他信息吗?只是
value\u-type
stored\u-type
。它是一个模板参数。通常
stored\u-type
int*
。还有一个
W说唱歌手
成员
value\u type operator()(strored\u type s)
存储的\u type operator()(value\u type v)
但是可以添加任何其他类型。您能提供一个使用这种包装器的示例吗?方法会是什么样的?您有关于接口类型和存储类型的任何其他信息吗?只是
value\u type
stored\u type
。它是一个模板参数。通常
stored\u type
int*
。还有一个
包装器
,其成员为
value\u-type操作符()(strored\u-type s)
存储的\u-type操作符()(value\u-type v)
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;
}