我刚刚在尝试重载 operator float()
时遇到了问题和 operator float() const
.我以为我可以使用这两个重载来为“做事”和“只读”提供不同的版本……但事实证明,对于包含这些重载的类的静态实例,我不能。
归结起来问题几乎可以简化为:
// Does some math and should convert to float
struct ToFloat
{
// float conversion here
operator float()
{
cout << "called operator float() of " << s << "\n";
f += 1.0f;
return f;
}
// just get current value here
operator float() const
{
cout << "called operator float() *const* of " << s << "\n";
return f;
}
float f;
std::string s;
};
// Uses a static and a normal member of ToFloat
struct Container
{
// return both instances (with some more math before)
operator float()
{
return s * m;
}
// just provide read access
operator float() const
{
return s * m;
}
static inline ToFloat s { 1.0f, "static" };
ToFloat m { 1.0f, "member" };
};
// Uses the container, but must also provide read-only access
struct Use
{
// Give me operator float() of my container
float get()
{
return c;
}
// Give me operator float() const of my container
float getC() const
{
return c;
}
Container c {};
};
int main()
{
Use u {};
printf("getC() %f \n\n", u.getC());
printf("get() %f \n\n", u.get());
printf("getC() %f \n\n", u.getC());
}
产生以下输出...
called operator float() of static
called operator float() *const* of member
getC() 2.000000
called operator float() of static
called operator float() of member
get() 6.000000
called operator float() of static
called operator float() *const* of member
getC() 8.000000
我真的不明白为什么 ToFloat
的静态实例总是使用非 const
转换,即使从声明为 const
的函数中调用?这里适用什么规则?
最佳答案
静态数据成员Container::s
只是ToFloat
类型。它总是被直接访问,从不通过对 this
的隐式取消引用。换句话说,容器的 const
运算符实际上是这样的:
operator float() const
{
return Container::s * this->m;
}
由此可见,Container::s
没有理由仅仅因为 this
是一个常量容器 *
。如果您希望它被视为 const
,则必须明确限定它:
operator float() const
{
return std::as_const(s) * m;
}
关于c++ - 使用运算符 float() 和带有静态成员的 float() const 的隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46473340/