使用运算符float()和float()const与静态成员进行隐式转换

时间:2017-09-28 15:45:45

标签: c++ static type-conversion const

我在尝试重载operator float()operator float() const时遇到了问题。我以为我可以使用两个重载来为“do things”和“just read”提供不同的版本......但事实证明,对于包含这些重载的类的静态实例,我不能。

将问题归结为几乎减少了这个问题:

// 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的函数调用?这里适用什么规则?

1 个答案:

答案 0 :(得分:1)

静态数据成员Container::s只是ToFloat类型。它总是直接访问,永远不会通过this的隐式解引用。换句话说,容器的const运算符实际上是这样的:

operator float() const
{
  return Container::s * this->m;
}

从这一点来看,显而易见的是,Container::s没有理由因为constthis而被视为const Container *。如果您希望将其视为const,则必须明确限定它:

operator float() const
{
  return std::as_const(s) * m;
}