在隐式转换中如何使用显式构造函数
我正在使用列出的资源 explicit 关键字。 >在这里和此帖子说:
将显式关键字在构造函数上前缀防止编译器将构造函数用于隐式转换。
现在,我编写了以下示例,该示例使用 explicit
复制constructor b :: b(const b&)
在隐式转换中。示例如下: mre,带有C ++ 14和-fno-elide-Constructors flag
struct A {
A()
{
std::cout<<"A's default ctor called"<<std::endl;
}
A(const A&)
{
std::cout<<"A's copy ctor called"<<std::endl;
}
};
class B
{
public:
B()
{
std::cout<<"B default ctor called"<<std::endl;
}
B(A)
{
std::cout<<"B's parametrized ctor called"<<std::endl;
}
explicit B(const B&)
{
std::cout<<"explicit B copy ctor called"<<std::endl;
}
};
int main()
{
B x;
//B a = x; //this fails AS EXPECTED
A y;
B p = y; //Why doesn't this fail as well? This uses the copy ctor in addition to the param ctor. How the explicit copy ctor is used here in implicit conversion
}
输出上述程序是:
B default ctor called
A's default ctor called
A's copy ctor called
B's parametrized ctor called
explicit B copy ctor called <--------------HOW IS THAT EXPLICIT CTOR IS USED HERE IN IMPLICIT CONVERSION?
因此,我的问题是如何在上述隐式转换中使用明确的副本CTOR。我的意思是,对于我当前的理解,我期望 b p = y;
失败,就像复制初始化 b a = x;
失败。我想知道这是标准允许的,还是编译器错误。
请注意
,在我给定的演示中,使用 -fno-elide-constructors
标志。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是良好的,由标准允许,如下所述。
可以使用 dcl.init#17.666.66.66.66.6.6.6.6.6.6.6.6.66.6.6.6.6.6.6.66.66.66.66.66.66> dcl.init .2 哪个指出:
(强调我的)
让我们将其应用于您的榜样。
在给定的示例中(
b p = y;
)源类型是a
,而目标类型为b 。现在,使用非明确的参数化CTOR
b :: B(a)
使用了从源类型到目标类型的用户定义转换,此处将在此处使用。此不明显的CTOR将以初始化器表达式作为参数调用。此外,此调用是类型
b
的 prvalue 。这里要注意的重要一件事是,此调用将用于 DirectInialize 名为
p
的对象。而且,由于在直接初始化上下文中可以使用显式CTOR,因此明确的副本可以并且将在此处使用。效果是 as-if 我们正在写:
This is well-formed and is allowed by the standard as explained below.
The behavior of your program can be understood using dcl.init#17.6.2 which states:
(emphasis mine)
Let's apply this to your example.
In the given example(
B p = y;
in particular) the source type isA
while the destination type isB
. Now there is a user-defined conversion available from the source type to the destination type using the non-explicit parameterized ctorB::B(A)
which will be used here.This non-explicit ctor will be called with the initializer expression
y
as its argument. Moreover, this call is a prvalue of typeB
.The important thing to note here is that this call will be used to direct-initialize the object named
p
. And since in direct initialization context the explicit ctor can be used, therefore the explicit copy ctor can and will be used here.The effect is as-if we're writing: