我正在尝试更新一个使用 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++)编译和运行。
Update To really simulate my real problem there was some information left out in the sample code above. In between the Value class and the usage is a few other classes. One that look like this:
class Config
{
public:
virtual Value getValue(const string& key) const = 0;
Value operator()(const string& key)
{
return getValue(key);
}
};
And the usage const wstring value2 = config("key");
That will give the error above when compiling but also IntelliSense will give other hints on whats wrong and it says: "More than one user-defined conversion from "Value" to "const std::wstring" applies:" and it points at both the regular constructor and the move constructor of basic_string. So it seem to have something to do with rvalues to do and I have been reading up on that, and understand the basics. But there is probably a lot I am missing.
I find that I can fix this problem by changing the usage to: const wstring&& value = config("key");
Then it seem like the VS2012 compiler understand which constructor it should use then.
Questions: * Are there a way to not use && in this example? * What is really happening here?
I put up the sample code on GitHub: https://github.com/Discordia/ImplicitTypeConversion