[英]Difference between return value and local variable
假设我有
#include <string>
class A
{
public:
template<class T>
operator T();
A child();
};
void f()
{
A a;
std::string s1 = a; // ok
std::string s2 = a.child(); // error (line 34)
s1 = a; // error (line 36)
s2 = a.child(); // error (line 37)
}
std :: string构造函数可以使用char *或std :: string引用,这就是赋值不明确的原因。 但是为什么我的编译器(VC ++ 10)抱怨第二个赋值而不是第一个赋值?
我正在寻找一种方法来优先使用模板转换运算符而不是重载的构造函数。
我收到以下错误:
1>------ Build started: Project: Plasma4Test, Configuration: Debug Win32 ------
1> Plasma4Test.cpp
1>d:\bitbucket\vx\projects\plasma4test\plasma4test.cpp(34): error C2440: 'initializing' : cannot convert from 'A' to 'std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
1>d:\bitbucket\vx\projects\plasma4test\plasma4test.cpp(36): error C2593: 'operator =' is ambiguous
1> c:\program files\microsoft visual studio 10.0\vc\include\xstring(772): could be 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(_Elem)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\xstring(767): or 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const _Elem *)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\xstring(762): or 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const std::basic_string<_Elem,_Traits,_Ax> &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> while trying to match the argument list '(std::string, A)'
1>d:\bitbucket\vx\projects\plasma4test\plasma4test.cpp(37): error C2593: 'operator =' is ambiguous
1> c:\program files\microsoft visual studio 10.0\vc\include\xstring(772): could be 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(_Elem)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\xstring(767): or 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const _Elem *)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\xstring(762): or 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const std::basic_string<_Elem,_Traits,_Ax> &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\xstring(707): or 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(std::basic_string<_Elem,_Traits,_Ax> &&)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> while trying to match the argument list '(std::string, A)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
对我来说这似乎是一个VC10错误,它与 std::string
无关 。
BUG ISOLATION:
我把它归结为以下示例:
#include <string>
class B
{
public:
B(char const*) { }
B(B&&) { }
};
class A
{
public:
operator char* const () { return 0; }
operator B () { return B(0); }
};
int main()
{
A a;
B b1 = a; // fine
B b2 = A(); // error C2440: 'initializing' : cannot convert from 'A' to 'B'
// No constructor could take the source type, or constructor
// overload resolution was ambiguous.
}
B
类有一个移动构造函数和一个构造函数,它接受一个const char*
。 当尝试从右rvalue
初始化b2
,VC10似乎无法选择转换运算符为B
Clang 3.2和GCC 4.7.2都选择转换运算符为B
C ++标准规则:
C ++标准第8.5 / 16段要求:
[对于这种复制初始化的情况,] “用户定义的转换序列可以从源类型转换为目标类型或(当使用转换函数时)到其派生类,如13.3.1.4所述,通过重载决议(13.3)选择最好的一个“
如果我们考虑我们的示例中从源类型( A
)到目标类型( B
)的所有可用转换序列,那么涉及A
的用户定义转换函数到char const*
转换序列需要进一步转换(通过B
的构造函数接受char const*
)以便到达目标类型 B
因此,它比使用A
的用户定义转换函数的B
(按照13.3.3.2)长一步,这使得后者更可取。
这似乎证实它是一个VC10错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.