【问题标题】:Overloading subscript operator in an user defined class C++在用户定义的类 C++ 中重载下标运算符
【发布时间】:2018-11-17 18:03:47
【问题描述】:

考虑以下类:

class SocialPrefNode{

public:

// Constructors & Destructor
SocialPrefNode( );
SocialPrefNode( char self, int ind, int link, bool stack, std::vector<SocialPrefNode*> pref,
                std::vector<SocialPrefNode*> worse, std::vector<SocialPrefNode*> indiff );

SocialPrefNode( const SocialPrefNode& copy );

~SocialPrefNode( );

// Setters
void set_id( char self );

void set_index( int ind );
void set_lowlink( int link );

void set_onstack( bool stack );

void set_pref( std::vector<SocialPrefNode*> prefs );
void set_pref( SocialPrefNode& prefs );

void set_worse( std::vector<SocialPrefNode*> wrs );
void set_worse( SocialPrefNode& wrs );

void set_indiff( std::vector<SocialPrefNode*> indiff );
void set_indiff( SocialPrefNode& indiff );

// Getters
char get_id( ){ return id; }

int get_index( ){ return index; }
int get_lowlink( ){ return lowlink; }

bool get_onstack( ){ return onstack; }

std::vector<SocialPrefNode*> get_preferences( ){ return preferences; }
std::vector<SocialPrefNode*> get_worse( ){ return worsethan; }
std::vector<SocialPrefNode*> get_indiff( ){ return indifference; }

// Operators
SocialPrefNode& operator=( const SocialPrefNode& copy );

private:

char id{ };

int index{ };
int lowlink{ };

bool onstack{ };

std::vector<SocialPrefNode*> preferences{ };
std::vector<SocialPrefNode*> worsethan{ };
std::vector<SocialPrefNode*> indifference{ };
};

std::ostream& operator<<( std::ostream& os, SocialPrefNode& node );

问题:有没有办法重载/覆盖/重新定义下标运算符 s.t.例如,可以在三个选项中访问一个选择向量。

即,假设:SocialPrefNode ordering{ }。我希望能够使用 ordering[ i ] 中的下标运算符 AND 能够在类中的三个向量中选择一个来执行下标/索引 i 。 p>

示例:想要访问SocialPrefNode orderingpreferences 向量中的第三个元素。然后,ordering[ 2 ] 可以访问所需的元素。

【问题讨论】:

  • 所以你有三个数据:实例ordering,subsript i,以及......要搜索的容器类型在哪里?
  • 你可以写一个operator[],它取0-2并返回一个std::vector&lt;SocialPrefNode*&gt;(偏好或比或冷漠)。当然,对于向量 0 中的元素 2,这需要像 x[0][2] 这样的多维下标。或者您可以为索引设置一个包装器类型,以便包装器附带要读取的向量的信息。

标签: c++ vector overloading subscript-operator


【解决方案1】:

一种可能的解决方案是使用幻像类型来包装要使用的向量。我关注了this blog post,并提出了以下解决方案。

// Wrapper need once in the complete project:
template <typename T, typename Parameter>
class NamedType
{
public:
    explicit NamedType(T const& value) : value_(value) {}
    explicit NamedType(T&& value) : value_(std::move(value)) {}
    T& get() { return value_; }
    T const& get() const { return value_; }
private:
    T value_;
};

// Only showing the new parts in your class!
class SocialPrefNode {
public:
    // One phantom type for each array index
    using preferences_index = NamedType<std::ptrdiff_t, struct preferences_Parameter>;
    using worsethan_index = NamedType<std::ptrdiff_t, struct worsethan_Parameter>;
    using indifference_index = NamedType<std::ptrdiff_t, struct indifference_Parameter>;

    // One operator[] for each array index type
    SocialPrefNode* operator[](preferences_index i) { return preferences[i.get()]; }
    SocialPrefNode* operator[](worsethan_index i) { return worsethan[i.get()]; }
    SocialPrefNode* operator[](indifference_index i) { return indifference[i.get()]; }
}

// Usage is simple assuming a SocialPrefNode s.
s[0]; // This will not work!
s[SocialPrefNode::preferences_index{ 0 }];  // Accessing preferences
s[SocialPrefNode::worsethan_index{ 0 }];    // Accessing worsethan
s[SocialPrefNode::indifference_index{ 0 }]; // Accessing indifference

如果你不介意添加外部依赖,可以直接使用NamedType作者的Github repo(类比这里扩展了一点)。

【讨论】:

  • 我真的很喜欢你上面的评论,这似乎是做我想做的最好的方式。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
  • 2021-10-12
  • 2013-09-06
  • 2012-07-06
  • 2011-01-29
相关资源
最近更新 更多