0

有人可以解释转换规则,以及何时转换不明确吗?我对以下案例感到有些困惑,它在 MSVC++ (Visual Studio 2010) 和 gcc-4.3.4 上给出了不同的答案。

#include <string>

class myStr
{
  std::string value;

public:
  myStr(const char* val) : value(val) {}
  operator const char*() const {return value.c_str();}
  operator const std::string() const {return value;}
};

myStr byVal();
myStr& byRef();
const myStr& byConstRef();

int main(int, char**)
{
  myStr foo("hello");
  std::string test;

  // All below conversions fail "ambiguous overload for 'operator='" in gcc
  // Only the indicated coversions fail for MSVC++
  test = foo;  // MSVC++ error "'operator =' is ambiguous"
  test = static_cast<std::string>(foo);

  test = byVal();  // MSVC++ error "'operator =' is ambiguous"
  test = static_cast<std::string>(byVal());  // MSVC++ error 
             // "'static_cast' : cannot convert from 'myStr' to 'std::string'"

  test = byRef();  // MSVC++ error "'operator =' is ambiguous"
  test = static_cast<std::string>(byRef());

  test = byConstRef();  // MSVC++ error "'operator =' is ambiguous"
  test = static_cast<std::string>(byConstRef());

  return 0;
}

哪些规则规定哪些转换是合法的?是否有任何合规的方法可以明确地使用一个myStr定义强制转换为const char*和的类const std::string

4

1 回答 1

2

隐式转换都是模棱两可的,因为std::string重载的赋值运算符同时采用const std::string&and const char*。这意味着您的两个转换运算符都是同样好的选择,因此存在歧义:

myStr -> std::string -> operator=(const std::string&)
myStr -> const char* -> operator=(const char*)

含糊不清static_cast是因为您使用演员表来创建临时std::string对象。std::string从 a或 a创建它同样有效const char*,因此再次考虑您的两个转换运算符。

myStr -> std::string -> static_cast<std::string>(std::string)
myStr -> const char* -> static_cast<std::string>(const char*)

您可以通过转换为参考来打破歧义:

test = static_cast<const std::string&>(foo);

这仍然会创建一个临时的,因为转换运算符返回一个对象。但是,该转换现在是隐式的,因此不能涉及多个用户定义的转换;因此,它只能通过你来完成,operator std::string()没有歧义。

myStr -> std::string -> static_cast<const std::string&>(std::string)
myStr -> const char* -> std::string -> static_cast<const std::string&>(std::string)
      ^^             ^^  two implicit user-defined conversions - not allowed

您还可以考虑更改转换运算符以返回const引用,以避免不必要的临时操作。

于 2012-06-27T13:09:33.260 回答