C++ 运算符 []
C++ operator []
我正在尝试实现运算符 [],它一次用于 Set,一次用于 Get,我需要区分这两种情况,对于 get,我需要抛出一个异常,如果返回值等于-1;而在 Set 的情况下,我只是覆盖值。
苹果[2] = X;
y=苹果[2];
我不知道如何区分这两种模式,我的函数签名是:
double& Security::operator[](QuarterType index){
if(index<0 || index>MAX_QUATERS){
throw ListExceptions::QuarterOutOfBound();
}
return evaluation[index].getValueAddress();
}
"Get" 版本可以引用 const
并标记为 const
:
const double& Security::operator[](QuarterType index) const
"Set"版本可以写成你现在的版本:
double& Security::operator[](QuarterType index)
有时当您需要强制调用 const
版本时,您可以 const_cast
您的对象为 const
类型。 (但是不要反过来做:如果原始对象是 const
,则丢弃 const
-ness 的行为是未定义的)。
但我个人认为这不必要地复杂化。摆脱运算符重载并编写单独的 get
和 set
函数可能更实用。您 可以 对 QuarterType
class 做一些事情:也许将特征系统注入其中,允许函数相应地处理特定的 QuarterType
实例。但这可能并不比使用不同名称的单独函数更好。
(如果 QuarterType
是一个大对象,则考虑传递 const QuarterType&
。这将防止获取值副本。)
查看 cppreference.com 上的 operator overloading 篇文章。 数组下标运算符部分准确解释了您的需求:
User-defined classes that provide array-like access that allows both
reading and writing typically define two overloads for operator[]
:
const and non-const variants:
struct T {
value_t& operator[](std::size_t idx) { return mVector[idx]; };
const value_t& operator[](std::size_t idx) const { return mVector[idx]; };
};
If the value type is known to be a built-in type, the const variant should return by value.
(continued)
因此,您应该定义 double Security::operator[](QuarterType index) const
,而不是 const double& Security::operator[](QuarterType index) const
。
I am trying to implement the operator [] that is to be used once for Set and once as Get
无法完成。您可以使用不同的签名(即 const 和非 const 版本)实现多个版本的运算符,但它们不会被正确调用。
相反,请考虑使用您需要的功能实现 set 和 get 函数。
您可以 return 来自 [] 运算符的代理对象,该对象具有针对目标类型的隐式转换 operator double
和 operator =
。如果对话运算符被调用并且你的值为-1你抛出,如果赋值被调用你赋值。
与 python 或 C# 等语言不同,C++ 不为其运算符提供获取和设置模式。因此,您必须编写 operator[]
以便它 return 是一个在您希望它被使用的任何上下文中使用时做正确事情的对象,这通常意味着引用。
注意我说的是通常;您还可以执行其他操作,例如 return 具有以下成员的 class 实例:
struct proxy
{
operator double() const;
void operator=(double x);
};
如果在需要双精度的上下文中使用此代理对象,它将调用隐式转换运算符,该运算符是为执行您的 get 操作而实现的。同样,如果有人给代理对象赋值,它会调用赋值运算符,它被实现来做你的集合操作。
(请注意,代理可能需要引用您的 Security
对象)
不过,这种方法并非没有困难;由于您的 return 值不是 double
或 double&
或类似类型,它可能会导致与重载解析的混淆,尤其是模板函数,并且在与 [= 一起使用时会造成很多混淆15=]。而且您的代理对象甚至不能在需要 double&
!
的上下文中使用
因此,这是万不得已的方法,当您被逼到角落并且必须根据假装的operator[]
进行访问时与 double
一起工作。在你诉诸于此之前,你真的应该寻求其他选择,例如:
- 重新设计您的程序,以便索引
Security
对象可以 return 引用 double
,而不需要更复杂的获取和设置操作。 (例如,更改不变量以便没有异常数据,或者在其他地方进行错误处理)
- 满足于使用专用的获取和设置操作。甚至给他们起更复杂的名字,以反映他们正在做的事情比人们通常认为的索引集合更重要。
- 重新设计 API 以便用户期望从
operator[]
获得具有各种重要行为的代理对象,而不是期望使用 operator[]
到 read/write double
个对象。
C++ 不容易区分
appple[2] = X;
y=apple[2];
最常见的解决方案是return一个代理对象:
struct AppleProxy
{
Security & obj;
unsigned index;
AppleProxy(Security &, unsigned) : ... {}
operator double() // your getter
{
return obj.GetAt(index);
}
operator=(double rhs)
{
obj.SetAt(index, rhs);
}
}
AppleProxy operator[](unsigned index) { return AppleProxy(*this, index); }
Proxy 需要特别注意细节,我省略了 const
正确性、生命周期管理、获取地址 (double & x = apple[2]; x = 17;
) 等
由于陷阱,我倾向于避免它们。
我正在尝试实现运算符 [],它一次用于 Set,一次用于 Get,我需要区分这两种情况,对于 get,我需要抛出一个异常,如果返回值等于-1;而在 Set 的情况下,我只是覆盖值。 苹果[2] = X; y=苹果[2];
我不知道如何区分这两种模式,我的函数签名是:
double& Security::operator[](QuarterType index){
if(index<0 || index>MAX_QUATERS){
throw ListExceptions::QuarterOutOfBound();
}
return evaluation[index].getValueAddress();
}
"Get" 版本可以引用 const
并标记为 const
:
const double& Security::operator[](QuarterType index) const
"Set"版本可以写成你现在的版本:
double& Security::operator[](QuarterType index)
有时当您需要强制调用 const
版本时,您可以 const_cast
您的对象为 const
类型。 (但是不要反过来做:如果原始对象是 const
,则丢弃 const
-ness 的行为是未定义的)。
但我个人认为这不必要地复杂化。摆脱运算符重载并编写单独的 get
和 set
函数可能更实用。您 可以 对 QuarterType
class 做一些事情:也许将特征系统注入其中,允许函数相应地处理特定的 QuarterType
实例。但这可能并不比使用不同名称的单独函数更好。
(如果 QuarterType
是一个大对象,则考虑传递 const QuarterType&
。这将防止获取值副本。)
查看 cppreference.com 上的 operator overloading 篇文章。 数组下标运算符部分准确解释了您的需求:
User-defined classes that provide array-like access that allows both reading and writing typically define two overloads for
operator[]
: const and non-const variants:struct T { value_t& operator[](std::size_t idx) { return mVector[idx]; }; const value_t& operator[](std::size_t idx) const { return mVector[idx]; }; };
If the value type is known to be a built-in type, the const variant should return by value.
(continued)
因此,您应该定义 double Security::operator[](QuarterType index) const
,而不是 const double& Security::operator[](QuarterType index) const
。
I am trying to implement the operator [] that is to be used once for Set and once as Get
无法完成。您可以使用不同的签名(即 const 和非 const 版本)实现多个版本的运算符,但它们不会被正确调用。
相反,请考虑使用您需要的功能实现 set 和 get 函数。
您可以 return 来自 [] 运算符的代理对象,该对象具有针对目标类型的隐式转换 operator double
和 operator =
。如果对话运算符被调用并且你的值为-1你抛出,如果赋值被调用你赋值。
与 python 或 C# 等语言不同,C++ 不为其运算符提供获取和设置模式。因此,您必须编写 operator[]
以便它 return 是一个在您希望它被使用的任何上下文中使用时做正确事情的对象,这通常意味着引用。
注意我说的是通常;您还可以执行其他操作,例如 return 具有以下成员的 class 实例:
struct proxy
{
operator double() const;
void operator=(double x);
};
如果在需要双精度的上下文中使用此代理对象,它将调用隐式转换运算符,该运算符是为执行您的 get 操作而实现的。同样,如果有人给代理对象赋值,它会调用赋值运算符,它被实现来做你的集合操作。
(请注意,代理可能需要引用您的 Security
对象)
不过,这种方法并非没有困难;由于您的 return 值不是 double
或 double&
或类似类型,它可能会导致与重载解析的混淆,尤其是模板函数,并且在与 [= 一起使用时会造成很多混淆15=]。而且您的代理对象甚至不能在需要 double&
!
因此,这是万不得已的方法,当您被逼到角落并且必须根据假装的operator[]
进行访问时与 double
一起工作。在你诉诸于此之前,你真的应该寻求其他选择,例如:
- 重新设计您的程序,以便索引
Security
对象可以 return 引用double
,而不需要更复杂的获取和设置操作。 (例如,更改不变量以便没有异常数据,或者在其他地方进行错误处理) - 满足于使用专用的获取和设置操作。甚至给他们起更复杂的名字,以反映他们正在做的事情比人们通常认为的索引集合更重要。
- 重新设计 API 以便用户期望从
operator[]
获得具有各种重要行为的代理对象,而不是期望使用operator[]
到 read/writedouble
个对象。
C++ 不容易区分
appple[2] = X;
y=apple[2];
最常见的解决方案是return一个代理对象:
struct AppleProxy
{
Security & obj;
unsigned index;
AppleProxy(Security &, unsigned) : ... {}
operator double() // your getter
{
return obj.GetAt(index);
}
operator=(double rhs)
{
obj.SetAt(index, rhs);
}
}
AppleProxy operator[](unsigned index) { return AppleProxy(*this, index); }
Proxy 需要特别注意细节,我省略了 const
正确性、生命周期管理、获取地址 (double & x = apple[2]; x = 17;
) 等
由于陷阱,我倾向于避免它们。