C++类型转换运算符代码,在 Visual Studio 2012 中无法编译,但在 Visual Studio 2005 中工作正常

C++ type cast operator code that won't compile in visual studio 2012, but worked fine in visual studio 2005

本文关键字:Studio Visual 编译 但在 2005 工作 2012 运算符 类型转换 代码 C++      更新时间:2023-10-16

我正在尝试更新一个旧项目,该项目已与visual studio 2005建立使用visual studio 2012,我得到一个错误,我无法解决。

在VS2005下正常工作的代码:

#include <iostream>
#include <string>
#include <sstream>
using std::cout;
using std::wcout;
using std::endl;
using std::wstring;
using std::string;

class Value 
{
public:
    Value(const wstring& value) 
    {
        v = value;
    }
    Value(Value& other)
    {
        this->v = other.v; 
    }
    template<typename T>
    operator T() const
    {
        T reply;
        std::wistringstream is;
        is.str(v);
        is >> reply;
        return reply;
    } 
    operator wstring() const 
    {
        return v;
    }

private:
    wstring v;
};

int main()
{
    Value v(L"Hello World");
    wstring str = v;
    wcout << str << endl;
    Value int_val(L"1");
    int i = int_val;
    cout << i + 1 << endl;
    return 0;
}

当我在VS2012下编译这个时,我在"wstring str = v;"行上得到一个错误,错误是:

error C2440: 'initializing' : cannot convert from 'Value' to 'std::basic_string<_Elem,_Traits,_Alloc>'
1>          with
1>          [
1>              _Elem=wchar_t,
1>              _Traits=std::char_traits<wchar_t>,
1>              _Alloc=std::allocator<wchar_t>
1>          ]
1>          No constructor could take the source type, or constructor overload resolution was ambiguous

我可以通过将操作符签名从'operator wstring() const'更改为'operator const wstring&() const'来修复它。但是为什么原始代码不能工作,即使它在VS2005中工作。

我没有在"int I = int_val;"这行上得到错误。

在cygwin(版本4.5.3)中也可以很好地编译和运行GCC (g++)。

为了真正模拟我的实际问题,上面的示例代码中遗漏了一些信息。在Value类和用法之间是一些其他类。它看起来像这样:

class Config
{
public:
    virtual Value getValue(const string& key) const = 0;
    Value operator()(const string& key) 
    {
         return getValue(key);
    }
};

和用法Const wstring value2 = config("key");

这将在编译时给出上述错误,但IntelliSense也会给出其他提示,说明错误所在,它说:"从"Value"到"const std::wstring"的多个用户定义转换适用于:",它指向basic_string的常规构造函数和move构造函数。所以它似乎和右值有关我已经读过了,了解了基本知识。但我可能错过了很多东西。

我发现我可以通过改变用法来解决这个问题:const wstring&和;Value = config("key");

那么看起来VS2012编译器应该知道它应该使用哪个构造函数。

问题:有没有办法不使用&&在这个例子中?这里到底发生了什么?

我把示例代码放在GitHub上:https://github.com/Discordia/ImplicitTypeConversion

用简单的(希望不是简化的)术语来说,在c++ 11中,您必须开始从左值和右值的角度考虑引用。基本上,c++ 11使您能够根据是否处理"临时"对象,以不同的方式处理对引用的操作。这使您能够将数据移动到对象内部,而不是在不同情况下进行复制。这样做的缺点是您看到的效果,旧代码对您正在处理的内容不够具体。还有更多的东西,这不是一个简短的SO答案可以完全解释的东西,但之前的答案给了一些很好的起点。我会重新编写您的代码以提供右值和左值操作符(听起来您已经在这样做了)。