1

我正在将 C++ 项目从 MSVC 2008 升级到 2010,并且由于新的 CComBSTR 移动构造函数 [CComBSTR( CComBSTR&& )],由于调用不明确,我收到编译器错误。

本质上,我们有一个 String 类,它与具有 CComBSTR 的强制转换运算符的 std::wstring 非常相似。这类似于以下代码:

class CString {
  public:
    // ...
    operator CComBSTR() {
      CComBSTR temp;
      /* Encoding conversion here */
      return temp;
    }
}

class CObjectConfig {
  public:
    CString GetName() const { return m_name; }

  private:
    CString m_name;
}

现在,在代码中的某些地方,我们执行以下操作:

CObjectConfig config = GetObjectConfig();
CComBSTR objectName( config.GetName() );

在 VS2008 中,这会起作用,因为 CString 对象将被隐式转换为 CComBSTR 右值,并且将调用 CComBSTR 的复制构造函数(采用 const CComBSTR&)来构造 objectName。

然而,在带有 C++0x 的 VS2010 中,编译器给出了一个模棱两可的调用错误,因为 CComBSTR 右值似乎同时适合复制构造函数和移动构造函数。

虽然有点笨拙,但我对这个问题的解决方案是 static_cast 对 GetName 的调用:

CComBSTR objectName( static_cast<const CComBSTR&>( config.GetName() ) );
// or
CComBSTR objectName( static_cast<CComBSTR&&>( config.GetName() ) );

这两行编译都没有错误,但我需要您就这是否非法、不好的做法或未定义提出建议。谢谢你。

4

1 回答 1

1

对我来说,这看起来像是一个 VC2010 错误。要么,要么我在我的电脑上错误地模拟了你的情况(我没有 VC2010)。这就是我正在做的事情:

#include <iostream>

class CComBSTR
{
public:
    CComBSTR() {std::cout << "CComBSTR()\n";}
    CComBSTR(const CComBSTR&) {std::cout << "CComBSTR(const CComBSTR&)\n";}
    CComBSTR(CComBSTR&&) {std::cout << "CComBSTR(CComBSTR&&)\n";}
};

class CString {
  public:
    // ...
    operator CComBSTR() {
      CComBSTR temp;
      /* Encoding conversion here */
      return temp;
    }
};

class CObjectConfig {
  public:
    CString GetName() const { return m_name; }

  private:
    CString m_name;
};

CObjectConfig GetObjectConfig()
{
    return CObjectConfig();
}

int main()
{
    CObjectConfig config = GetObjectConfig();
    CComBSTR objectName( config.GetName() );
}

对于 g++-4.4 和 clang(使用 -std=c++0x)的我来说,这编译得很好。它要么调用或省略对 CComBSTR(CComBSTR&&) 的调用。我对解决这个可疑错误的建议很简单:

CComBSTR objectName( CComBSTR(config.GetName()) );

这相当于您的:

CComBSTR objectName( static_cast<CComBSTR&&>( config.GetName() ) );

但没有那么可怕(而且同样有效)。如果您想继续使用 static_cast,请使用 cast to CComBSTR&&,因为这可能比从 const 左值构造更有效。

于 2011-03-08T01:15:52.490 回答