在用户定义的 class C++ 中重载下标运算符
Overloading subscript operator in an user defined class C++
考虑以下 class:
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 );
问题:有没有办法overload/override/redefine下标运算符s.t。例如,人们可以从三个选项中选择一个向量。
即,假设:SocialPrefNode ordering{ }
。我希望能够使用下标运算符,如 ordering[ i ]
AND 能够在 class 的三个向量中选择一个,对于 subscript/index 我要表现得很好。
示例:想要访问 SocialPrefNode ordering
的 preferences
向量中的第三个元素。然后,ordering[ 2 ]
并因此可以访问所需的元素。
一个可能的解决方案是使用幻像类型来包装要使用的向量。我跟着 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(其中class相对于在这里)。
考虑以下 class:
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 );
问题:有没有办法overload/override/redefine下标运算符s.t。例如,人们可以从三个选项中选择一个向量。
即,假设:SocialPrefNode ordering{ }
。我希望能够使用下标运算符,如 ordering[ i ]
AND 能够在 class 的三个向量中选择一个,对于 subscript/index 我要表现得很好。
示例:想要访问 SocialPrefNode ordering
的 preferences
向量中的第三个元素。然后,ordering[ 2 ]
并因此可以访问所需的元素。
一个可能的解决方案是使用幻像类型来包装要使用的向量。我跟着 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(其中class相对于在这里)。