【问题标题】:strange implicit conversion on C++C++ 上奇怪的隐式转换
【发布时间】:2015-01-14 14:29:52
【问题描述】:

我有一个关于意外转换的问题:

class BadString
{
 public:
    BadString(char const*);
    ...
    char& operator[] (size_t);            //(1)
    char const& operator[] (size_t);

    operator char* ();                    //(2)
    operator char const* ();

};

int main()
{
    BadString str("correkt");
    str[5] = 'c';  //possibly an overload resolution ambiguity !!!
}

解释是这样的:

(1) 处的下标运算符似乎是完美匹配。然而,它不是很完美,因为参数 5 的类型为 int,并且运算符需要 size_t(无符号整数或无符号长整数,但绝不是整数)。尽管如此,一个简单的标准整数转换使得 (1) 很容易实现。 但是,还有另一个候选:内置的下标运算符。实际上,如果我们将转换运算符 (2) 应用于 str,我们将获得一个指针类型,现在应用内置的下标运算符。此运算符采用 ptrdiff_t 参数,在许多平台上它等价于 int。

我知道 (1) 的原始参数不匹配,然后会发生隐式转换,但我不明白为什么编译器会尝试使用 (2) 转换 str。

谢谢。

【问题讨论】:

  • 你的代码不应该编译:你正在通过返回类型重载operator[]
  • 您需要使函数char const& operator[] (size_t) 保持不变,例如char const& operator[] (size_t) const;
  • 引用内容时最好注明出处。
  • 隐含 operator char * 无论如何都是个坏主意
  • “C++ 模板,完整指南”,VanDeVoorde & Josuttis:B.2.1 成员函数的隐含参数

标签: c++ implicit-conversion


【解决方案1】:

如果我像这样“扩展”你的代码并使第二个下标运算符方法为 const,那么结果将是

#include <iostream>
#include <cstring>

class BadString {
  public:
      char s[1024];
      BadString(const char* s_)  {
          strncpy(s, s_, strlen(s_) + 1);
      }
      char& operator[](size_t pos) {
          return s[pos];
      }
      const char& operator[](size_t pos) const {
          return s[pos];
      }

      operator char*() {
          std::cout << "operator char*\n";
      }

      operator const char*() {
          std::cout << "operator const char*\n";
      }
};

int main() {
    BadString bs("correkt");
    bs[5] = 'c';
    std::cout << bs.s << "\n";
}

然后编译运行,按预期运行,输出只有一行

correct

发生(2) 隐式转换运算符等事实意味着您没有提供有关BadString 类的完整信息。也许你应该这样做。

当然,如果它像提供的示例中那样实现,则没有任何理由 调用(2)隐式转换运算符。

UPD: 考虑到您在评论中提到的内容,我想这样做的目的是 operator const char*() 是那种显式转换之类的

(const char*)bs

返回指向数组s 的第一个元素的指针,bs 持有该元素。那当然是, 不正确,而且有点难看,但我看到的只有一个选项。

【讨论】:

  • 我认为在书上,在您的示例中,实现 operator const char*() 的目的是返回 s[0] 的等价物。我完全明白为什么您的示例没有重载解决问题。
  • s[0] 将调用非常量 bs.operator[](0),这将返回对 s[0] 的引用,根据“定义”,它是 *s,类型为 char。我不明白,会发生什么转换?
  • "如果我们将转换运算符(2)应用于str,我们得到一个指针类型,..."
  • 这正是我在 UPD 中回答的意思。是显式转换。
猜你喜欢
  • 1970-01-01
  • 2013-06-11
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 2016-01-23
相关资源
最近更新 更多