转发构造函数调用基类的复制构造函数2次
Forwarding constructors calls 2 times copy constructor of base class
以下代码将构造函数从基类转发到派生类。
为什么要调用2个复制构造函数?背景中发生了什么?
用g++编译。
#include <iostream>
using namespace std;
struct A {
A() { cout << "A" << endl; }
A(const A&) { cout << "A(const A&)" << endl; }
template<typename T> A(T a); // Needed to compile :-O
};
template<typename T>
struct C : public T { using T::T; };
int main()
{
A a;
C<A> ca(a);
//C<A> caa(ca);
return 0;
}
输出为:
A
A(const A&)
A(const A&)
通过在A
中定义构造函数模板,C
将获得一个具有类似签名的构造函数模板。它的定义类似于:
template<typename T>
struct C : public T
{
//using T::T;
C() = default;
C(C const&) = default;
template<typename U> C(U a) : T( std::forward<U>(a) ) {}
};
这现在调用A
的复制构造函数两次:一次用于按值获取参数。第二个调用来自T( std::forward<U>(a) )
调用A
的复制ctor。这让我很惊讶,因为你会期望一个继承的ctor调用它所继承的基类的确切ctor。但事实并非如此,重载解析选择的不是A
的ctor模板,而是纯拷贝的ctorA(A const&)
(见下文)。
有趣的是,它不太关心A
中的构造函数模板做什么,只需要声明它。这就是为什么在OP中,定义可能会丢失;它也可以被删除(这可能是一个缺陷?)。
只需要在初始化CCD_ 10的过载解析期间选择CCD_。这里的情况是这样的:参数是A
类型的右值,它可以直接绑定到const A&
引用,这是a的副本ctor所要求的。由于引用绑定是直接的,并且不派生到基转换,因此副本ctor列为精确匹配。A
中的ctor模板也被列为"精确匹配",但由于重载集中有一个级别相同的模板和非模板函数,因此首选非模板函数(复制ctorA(A const&)
)。
对A::A(const A&)
的一个调用是C<A>
的基类构造函数。
另一个用于复制pass-by-value参数。
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用