Lig*_*ica 4 c++ visual-studio inherited-constructors c++17
对于以下程序:
#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);
}
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会给出:
$ g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Foo()
Foo(const Foo&)
~Foo()
~Foo()
Run Code Online (Sandbox Code Playgroud)
VS 2017(也在 C++17 模式下)给出:
Foo()
Foo(const Foo&)
Foo(const Foo&)
~Foo()
~Foo()
~Foo()
Run Code Online (Sandbox Code Playgroud)
谁是对的,为什么?
(我们也不要忘记 VS 2017 没有正确执行强制复制省略。所以它可能只是副本是“真实的”,但 GCC 根据 C++17 规则省略了它,而 VS 没有......)
Visual Studio 似乎还没有实现P0136。正确的 C++17 行为是一个副本,正确的 C++14 行为是两个副本。
C++14 规则(N4140:[class.inhctor])将解释:
struct B : A
{
using A::A;
};
Run Code Online (Sandbox Code Playgroud)
作为:
struct B : A
{
B(Foo f) : A(f) { }
};
Run Code Online (Sandbox Code Playgroud)
引入的构造函数在 p3 中指定,p8 中的 mem-initializer 等价物。因此,您将获得两份副本Foo:一份进入B的合成构造函数,一份进入A的真实构造函数。
作为 P0136 的结果,C++17 规则非常不同(N4659:[class.inhtor.init]):在那里,我们直接调用A的构造函数。这不像我们要再添加一个新的构造函数B——而且它不是一种在语言中可以表达的机制。而且因为我们直接调用A(Foo),这只是一个副本而不是两个。
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |