是否在调用基本ctor时将args复制到继承的构造函数? [英] Should args to inherited constructors be copied when invoking the base ctor or not?

查看:112
本文介绍了是否在调用基本ctor时将args复制到继承的构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于以下程序:

#include <iostream>

struct Foo
{
    Foo() { std::cout << "Foo()\n"; }
    Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; }
    ~Foo() { std::cout << "~Foo()\n"; }
};

struct A
{
    A(Foo) {}
};

struct B : A
{
    using A::A;
};

int main()
{
    Foo f;
    B b(f);
}

GCC给出:

$ g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Foo()
Foo(const Foo&)
~Foo()
~Foo()

VS 2017(也在C ++ 17模式下)提供:

VS 2017 (also in C++17 mode) gives:

Foo()
Foo(const Foo&)
Foo(const Foo&)
~Foo()
~Foo()
~Foo()

谁是对的,为什么?

(让我们也不要忘记VS 2017未正确执行强制性的复制省略.因此,可能是该复制是真实的",但GCC根据C ++ 17规则将其删除,而VS却没有...)

推荐答案

似乎Visual Studio并未实现

It appears that Visual Studio doesn't implement P0136 yet. The correct C++17 behavior is a single copy, the correct C++14 behavior was two copies.

C ++ 14规则( N4140:[class.inhctor] )会解释:

The C++14 rules (N4140:[class.inhctor]) would interpret:

struct B : A
{
    using A::A;
};

为:

struct B : A
{
    B(Foo f) : A(f) { }
};

在p3中指定了引入的构造函数,在p8中指定了mem-initializer等效项.因此,您得到了Foo的两个副本:一个副本到B的综合构造函数中,一个副本到A的真实构造函数中.

The introduced constructors are speciifed in p3, the mem-initializer equivalence in p8. Hence you get two copies of Foo: one into B's synthesized constructor and one into A's real constructor.

由于P0136而导致的C ++ 17规则非常不同(

The C++17 rules, as a result of P0136, are very different (N4659:[class.inhtor.init]): there, we directly invoke A's constructor. It's not like we're adding a new constructor to B anymore - and it's not a mechanism that's otherwise expressible in the language. And because we're directly invoking A(Foo), that's just the one single copy instead of two.

这篇关于是否在调用基本ctor时将args复制到继承的构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆