我有一个像这样的容器类:
class A {
public:
// assuming all the other operators used below
// have been defined.
// ...
A operator()(const A& a) const {
A r(a.size());
for (int i = 0;i < a.size();++i) r[i] = data[a[i]];
return r;
}
private:
std::vector<int> data;
};
所以我可以做这样的事情:
A a, b, c;
// ... initialize data here...
c = a(b); // I can index a by b
现在我想让索引容器a(b)
可分配,例如
a(b) = c;
例如,如果 a
为 {1, 2, 3, 4}
并且 b
为 {0,2}
,c
是 {0,0}
,上面的行应该给我 a = {0,2,0,4}
。因为{0,2}
索引的a
是a
中的{1,3}
,并将它们设置为c {0,0}
会给我这个。
怎么做?
最佳答案
您不能直接使用类型A
来执行此操作。您将需要一个映射或引用回该对象的中间类型。作为一个简单的非最佳示例:
#include <functional>
#include <vector>
class A
{
public:
class Ref
{
private:
friend class A;
std::vector<std::reference_wrapper<int>> refs;
Ref( A & obj, A & idx )
{
refs.reserve( idx.data.size() );
auto val_it = obj.data.begin();
for( auto i : idx.data ) {
ref.emplace_back( std::ref( data[i] ) );
}
}
public:
Ref & operator=( const A & obj )
{
auto obj_it = obj.data.begin();
for( auto ref : refs ) {
ref.get() = *obj_it++;
}
return this;
}
};
// ...
Ref operator()( const A & idx )
{
return Ref( *this, idx );
}
private:
std::vector<int> data;
};
然后事情开始变得棘手,因为您希望能够在这些基于引用的 View 和原始类型之间进行转换。
最简单的方法是在实现时保留 const 运算符(请注意,我的运算符是非 const):即它仍然返回类型 A
,这是有道理的。但您可能希望能够从 A::Ref
构建新的 A
,因此您需要一个如下的构造函数:
A::A( const Ref & r )
{
data.reserve( r.refs.size() );
auto r_it = r.refs.begin();
for( auto ref : r.refs ) {
data.push_back( ref.get() );
}
}
无论如何,这是一个让您入门的简单概念,并且可以尝试一下。
关于c++ - 如何使我自己的容器建立索引并可分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39876285/