奇怪的C ++隐式转换

时间:2015-01-14 14:29:52

标签: c++ implicit-conversion

我对意外转换有疑问:

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(unsigned int或unsigned long,但绝不是int)。然而,简单的标准整数转换使得(1)容易生存。   但是,还有另一个候选者:内置下标运算符。实际上,如果我们将转换运算符(2)应用于str,我们将获得指针类型,现在应用内置的下标运算符。此运算符采用ptrdiff_t参数,该参数在许多平台上等效于int。

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

谢谢。

1 个答案:

答案 0 :(得分:2)

如果我'扩展'你的代码并使第二个下标运算符方法为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的第一个元素的指针。那当然是 不正确,有点难看,但我看到了唯一的选择。