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;
}