非const复制构造函数和隐式转换返回值 [英] Non-const copy constructor and implicit conversions on return value
问题描述
请考虑以下C ++代码:
struct B {};
struct A
{
A(int);
A(A&); // missing const is intentional
A(B);
operator B();
};
A f()
{
// return A(1); // compiles fine
return 1; //不编译
}
这在MSVC ++ 2010上编译得很好在MSVC它甚至工作,如果我删除 B
一起)。它不在GCC 4.6.0上:
conv.cpp:在函数'A f()':
conv.cpp:13:9:错误:没有匹配的函数调用'A :: A(A)'
conv.cpp:13:9:注意:候选人是:
conv.cpp :6:2:note:A :: A(B)
conv.cpp:6:2:注意:没有已知的转换从参数1从'A'到'B'
conv.cpp: 5:2:note:A :: A(A&)
conv.cpp:5:2:note:没有已知的从参数1转换为'A'到'A&'
conv.cpp :4:2:note:A :: A(int)
conv.cpp:4:2:注意:参数1从'A'到'int'的已知转换
令人困惑的是消息没有已知的转换从参数1从'A'到'B'
。考虑到 A :: operator B()
的定义很好,这是怎么回事呢?
错误在被拒绝的候选人列表上是相当清楚的。问题是,涉及C ++语言中的用户定义转换的隐式转换序列限于单个用户定义的转换:
§13.3。 3.1.2 [over.ics.user] / 1用户定义的转换序列包括一个初始标准转换序列,后面跟着一个用户定义的转换(12.3),然后是第二个标准转换序列。
标准转换序列在§4[conv]中定义:
[...]标准转换序列是按以下顺序的标准转换序列
以下集合:lvalue-to-rvalue转换,数组到指针的转换和函数到指针的转换。
- p>零或一个资格转换。
问题是,通过应用单个用户定义的转换,从点a) int
rvalue到点b) B
特别地,所有可用的转换序列都以用户定义的转换开始(隐式构造函数 A(int)
),产生 A
右值。从那里,rvalue不能绑定到调用 A :: A(A&)
的非const引用,因此路径被丢弃。所有其他路径需要第二个用户定义的转换,不允许,实际上只有其他路径,使我们指向b)需要两个其他用户定义的转换总共3。
Consider the following C++ code:
struct B { };
struct A
{
A(int);
A(A&); // missing const is intentional
A(B);
operator B();
};
A f()
{
// return A(1); // compiles fine
return 1; // doesn't compile
}
This compiles fine on MSVC++ 2010 (in fact, on MSVC it even works if I remove B
altogether). It doesn't on GCC 4.6.0:
conv.cpp: In function ‘A f()’:
conv.cpp:13:9: error: no matching function for call to ‘A::A(A)’
conv.cpp:13:9: note: candidates are:
conv.cpp:6:2: note: A::A(B)
conv.cpp:6:2: note: no known conversion for argument 1 from ‘A’ to ‘B’
conv.cpp:5:2: note: A::A(A&)
conv.cpp:5:2: note: no known conversion for argument 1 from ‘A’ to ‘A&’
conv.cpp:4:2: note: A::A(int)
conv.cpp:4:2: note: no known conversion for argument 1 from ‘A’ to ‘int’
What's confusing me is the message no known conversion for argument 1 from ‘A’ to ‘B’
. How can this be true considering that A::operator B()
is very well defined?
The error is quite clear on the list of candidates that were rejected. The problem is that implicit conversion sequences involving a user defined conversion in the C++ language are limited to a single user defined conversion:
§13.3.3.1.2 [over.ics.user]/1 A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user-defined conversion (12.3) followed by a second standard conversion sequence.
The standard conversion sequences are defined in §4[conv]:
[...] A standard conversion sequence is a sequence of standard conversions in the following order
Zero or one conversion from the following set: lvalue-to-rvalue conversion, array-to-pointer conversion, and function-to-pointer conversion.
Zero or one conversion from the following set: integral promotions, floating point promotion, integral conversions, floating point conversions, floating-integral conversions, pointer conversions, pointer to member conversions, and boolean conversions.
Zero or one qualification conversion.
The problem is that your code cannot get from point a) int
rvalue to point b) B
by applying a single user defined conversion.
In particular, all conversion sequences that are available start with a user defined conversion (implicit constructor A(int)
) that yield an A
rvalue. From there, the rvalue cannot be bound to a non-const reference to call A::A( A& )
, so that path is discarded. All the other paths require a second user defined conversion that is not allowed, and in fact the only other path that would get us to point b) requires two other user defined conversions for a total of 3.
这篇关于非const复制构造函数和隐式转换返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!