【问题标题】:Ambiguous overload when using many typecasts operator overloads使用许多类型转换运算符重载时的模棱两可的重载
【发布时间】:2016-10-23 16:48:03
【问题描述】:

我想为字符串创建一个 wrapperClass。我还希望该类能够返回 wrapperClass 的地址和存储(包装)字符串的地址:

void FunctionString(string*);
void FunctionWrappedString(wrappedString*);

int main(){
   wrappedString wrappedStringObject;

   FunctionString(&wrappedStringObject);
   FunctionWrappedString(&wrappedStringObject);

   wrappedString anotherWrappedStringObject;

   if(wrappedStringObject == anotherWrappedStringObject){
    // code
   }
}

以下是课程的重要部分:

class wrappedString{
   typedef char* string;

   string storedString;

   operator string*(){
      // some code
      return &storedString;
   }

   operator wrapperString*(){
      // some code
      return this;
   }

  operator string(){
    // some code
    return storedString;
  }

}

但是,当我使用比较运算符时,这些都失败了:

if(wrappedStringObject == anotherWrappedStringObject){
  // code
}

说候选是:operator==(string,string) and operator==(string*,string*)

【问题讨论】:

  • 一些友好的建议——过多的转换操作符会导致许多不可预见的问题,即使你确实让它编译成功。诸如被调用的代码之类的事情您没想到只是其中之一。如果您想返回 std::string,请调用函数 get_string 而不是强制转换为 string()
  • @PaulMcKenzie:或者,定义强制转换运算符,但将所有(或除了一两个)情况设为explicit(需要 C++11)。 explicit operator std::string*explicit operator std::string
  • 旁注:typedef char* string;?!?为什么?这只是混淆用户的好方法。您的if(wrappedStringObject == anotherWrappedStringObject),即使它有效,最终会测试两个char* 是指向相同内存地址 的指针,而不是指向具有相同内容 的字符串的指针。
  • 我希望能够将此类插入到 char* 函数中,而不会出现太多问题或代码修改。 @ShadowRanger 感谢您显示显式关键字。每次添加 (string*) 仍然不太理想,但至少它有效。
  • @ClemsonCoder:这种用法不一定需要强制转换,假设您可以从不获取包装器本身的地址,只需by overloading operator&(这基本上是这样做的唯一合法案例)。这样做会使&mywrappedstring 产生一个引用包装对象成员的char**(又名string* 和你的typedef)。

标签: c++ pointers operator-overloading wrapper smart-pointers


【解决方案1】:

多个隐式转换运算符导致此问题。如果目标是让包装的string 对象表现得像string(实际上是char*?!?),那么只允许一个隐式转换运算符,而留下其余的explicit 以降低风险的不当行为。这仅适用于 C++11,但无论如何您现在都应该使用它:

class wrappedString{
   typedef char* string;

   string storedString;

   explicit operator string*(){
      // some code
      return &storedString;
   }

   explicit operator wrapperString*(){
      // some code
      return this;
   }

   operator string(){
     // some code
     return storedString;
   }

}

有了这个定义,if(wrappedStringObject == anotherWrappedStringObject){ 将只使用string 重载,而不是string* 重载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 2010-12-10
    • 1970-01-01
    • 2019-09-12
    • 2014-09-26
    • 1970-01-01
    相关资源
    最近更新 更多