c++ - 不在 Visual Studio 2012中编译的C++ 类型转换运算符代码,但在 Visual Studio 2005中工作良好

  显示原文与译文双语对照的内容

我正在尝试更新使用 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

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

我在行"int_val = ;"上没有出现错误。

这也与gcc编译并运行良好在cygwin( 版本 4.5.3 ) ( G++ ) 。

为了真正模拟我的实际问题,需要花费的更新时间。上面的示例代码中有一些信息。 在值类和用法之间还有几个其他类。 一个看起来像这样:


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

 Value operator()(const string& key) 
 {
 return getValue(key);
 }
};

以及用法常量 wstring value2 = 配置("") ;

这将在编译时给出上面的错误,但智能感知也会给出其他提示的错误并说明: "不止一个user-defined转换从"值""wstring::"适用:"它指向普通构造函数和移动basic_string的构造函数。 所以它似乎与rvalues做了一些事情,我一直在阅读,并理解基础知识。 但有可能我错过了很多。

我发现可以通过将用法更改为: wstring&& 值= 配置("键") ;

然后,VS2012编译器就会理解它应该使用哪个构造函数。

问题:* 在这里示例中没有使用 &&的方法? * 这里到底发生了什么?

我在GitHub上安装了示例代码: https://github.com/Discordia/ImplicitTypeConversion

时间:

在简单的( 希望不简化) 术语中,使用 C++11,你必须开始考虑关于左值和右值的引用。 基本上,C++11让你能够以不同的方式处理引用的操作,这取决于你是否正在处理"临时"对象。 这让你能够做一些事情,比如将数据移动到你的对象内部而不是在不同的情况下复制。 这就是你所看到的效果,其中旧代码没有足够的特殊,你正在处理。 更重要的是,它不是真正的东西,可以在短的时间内完全解释,但以前的答案给出了一些好的地方来开始。 我会修改你的代码以提供右值和左值运算符( 这听起来你已经在做你想做的事情了) 。

...