如何使用内置返回类型重载运算符?
How to overload operators with a built-in return type?
假设我有一个类,它包装了一些数学运算。让我们使用一个玩具示例
class Test
{
public:
Test( float f ) : mFloat( f ), mIsInt( false ) {}
float mFloat;
int mInt;
bool mIsFloat;
};
我想使用以下原型创建一个运算符重载:
float operator=( const Test& test )
{
if ( !test.mIsFloat ) return *this; // in this case don't actually do the assignment
return test.mFloat; // in this case do it.
}
所以我的问题是:我可以使用内置返回类型重载运算符=吗? 如果是这样,有没有办法引用内置类型?
我知道如果我用类包装内置组件,我可以做到这一点。但在这种情况下,我想让赋值运算符在 LHS 上使用内置类型
用法示例:
Test t( 0.5f );
float f = t; // f == 0.5
int i = 0;
i = t; // i stays 0.
更新:非常感谢您的帮助。从玩具的例子中扩展一点,以便人们理解我真正想做的事情。
我有一个配置系统,允许我从不同类型的参数树中获取配置参数(它们可以是整数、浮点数、字符串、数组等)。
我可以通过如下操作从树中获取项目:
float updateTime = config["system.updateTime"];
但"system.updateTime"可能不存在。或者属于错误的类型。通常对于配置,我有一个默认值块,然后代码来覆盖配置中的默认值:
float updateTime = 10;
const char* logFile = "tmp.log";
... etc etc...
我想做这样的事情:
updateTime = config["system.updateTime"];
如果存在替代,则操作成功。因此,如果 operator[] 的返回是树中的"无效"节点,则通常不会发生赋值。
现在我用这样的函数来解决它:
getConfig( config, "system.updateTime", updateTime );
但我更喜欢使用赋值运算符。
如果我愿意创建类来包装内置,我可以这样做。
class MyFloat
{
operator=( const Test& test ) { if (test.isValidNode() ) f = test.float(); return *this; }
float f;
}
但显然,最好不要用琐碎的类包装内置函数,只是为了重载赋值。问题是 - 这在 c++ 中可能吗?
根据您的示例,您真正想要的是一个隐式转换运算符:
class Test
{
// ...
public:
operator float() const;
};
inline Test::operator float() const
{
return mIsFloat ? mFloat : mInt;
}
如果你想有条件地做作业,那么你需要采取另一种方法。 命名方法可能是最好的选择,考虑到所有因素......像这样:
class Test
{
public:
bool try_assign(float & f) const;
};
inline bool Test::try_assign(float & f) const
{
if (mIsFloat) {
f = mFloat;
}
return mIsFloat;
}
无论你做什么,都要注意你引入的语法糖不会导致代码不可读。
你已经有一个从float
到Test
的隐式转换,以转换构造函数的形式
class Test
{
public:
/* ... */
Test( float f ) : mFloat( f ) /*...*/ {}
};
这将支持以下转换:
Test t(0.5f);
您可能还需要一个复制分配运算符,以便从float
到Test
进行进一步的隐式转换:
class Test
{
public:
Test& operator=(float f) { mFloat = f; return *this; }
};
t = 0.75; // This is possible now
为了支持从Test
到float
的隐式转换,你不使用operator=
,而是使用自定义的强制转换运算符,声明并实现如下:
class Test
{
public:
/* ... */
operator float () const { return mFloat; }
};
这使得隐式转换成为可能,例如:
float f = t;
顺便说一句,您在这里发生了另一个隐式转换,您甚至可能没有意识到。 在此代码中:
Test t( 0.5 );
文字值0.5
不是float
,而是double
。 为了调用转换构造函数,必须将此值转换为float
,这可能会导致精度损失。 要指定float
文本,请使用f
后缀:
Test t( 0.5f );
使用模板专用化:
class Config {
template<typename T>
void setValue(const std::string& index, T& value); //sets the value if available
};
template<float>
void Config::setValue(const std::string& index, float& value){...} //only sets float values
template<int>
void Config::setValue(const std::string& index, int& value){...} //only sets int values;
不能对基本类型"重载/添加"运算符,但可以为类型Type
运算符。但这不会是operator =
而是operator >>
——就像在istream
s中一样。
class Test
{
public:
float mFloat;
int mInt;
bool mIsFloat;
Test& operator >> (float& v) { if (mIsFloat) v = mFloat; return *this; }
Test& operator >> (int& v) { if (!mIsFloat) v = mInt; return *this; }
};
然后,您可以:
int main() {
float v = 2;
Test t = { 1.0, 2, false };
t >> v; // no effect
t.mIsFloat = true;
t >> v; // now v is changed
}
更新
我想做这样的事情:
updateTime = config["system.updateTime"];
然后根据我的建议,你来了:
config["system.updateTime"] >> updateTime;
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- C++20概念:需要运算符重载
- 使用赋值运算符重载从类中返回jobject
- 在运算符重载定义中使用成员函数(const错误)
- 字节到位运算符重载C++
- 为什么在运算符重载时需要参考?
- 类中 c++ 的运算符 + 重载
- 算术复合运算符重载为非成员
- 运算符重载 (+),用于添加两个具有 C++ 的数组
- 交换运算符 + 重载会导致无限递归
- 如何理解新的运算符重载?
- 向量保持复数的运算符重载
- 如何创建运算符重载?
- 链接列表运算符重载没有打印出我想要的内容
- C++:需要帮助了解运算符重载错误
- 使用模板化运算符重载 XOR 运算符失败
- 如何确保接受的C++模板类型使运算符重载?
- 运算符重载使用运算符+添加类模板