继承的构造函数的定义(主体)是什么样的
What does the definition(body) of an inherited constructor look like?
来自我对SO和cpp首选项链接的答案的阅读
继承的构造函数等效于具有空主体和成员初始值设定项列表的用户定义构造函数,该列表由单个嵌套名称说明符组成,该说明符将其所有参数转发给基类构造函数。
我得出的结论是,下面的类D
和E
的行为应该相同。
#include <string>
#include <utility>
using namespace std;
class B
{
public:
B(string&& a) : a(move(a))
{
}
string a;
};
class D : public B
{
public:
using B::B;
};
class E : public B
{
public:
E(string&& a) : B(a)
{
}
};
string foo()
{
return "bar";
}
int main()
{
D d = foo();//This compiles
E e = foo();//This does not compile
return 0;
}
E e = foo()
编译失败是正确的,因为B
的构造函数只接受string&&
。但是,D d = foo()
过得很好。为什么?使用的编译器是 clang3.5。
编辑:此外,正如本答案中所解释的,完美的转发习惯用法不能替代继承构造函数。那么,身体到底是什么样子的呢?
但是,D d = foo() 可以正常通过。为什么?
因为using B::B
有效地将临时字符串直接传递给B
的构造函数,在那里它仍然可以绑定&&
(即它的值类别仍然是xvalue),然后进行任何额外的派生类初始化(如果有其他数据成员,VDT等)。 这是非常可取的,因为使用基类构造函数的目的是允许相同的客户端使用。
(这与 E(string&&)
形成鲜明对比,其中命名的 a
参数不再被视为 xvalue(即将过期的临时)可以传递给 B::B
。
如果你还没有,你可能也想看看(std::forward
)[http://en.cppreference.com/w/cpp/utility/forward]...它有助于完美转发参数)
标准中关于派生类中继承的构造函数定义的外观的措辞比 cppreference 描述所暗示的内容更明确一些,但后者中的关键短语是转发其所有参数。换句话说,参数的值类别被保留,而E
的定义不会这样做,因此无法编译。
来自 N3337, §12.9/8[class.inhctor]
...
隐式定义的继承构造函数执行类的初始化集,该初始化将由用户编写的内联构造函数为该类执行,该构造函数具有 mem-initializer-list,其唯一的 mem 初始值设定项具有mem-initializer-id,用于命名在 using-声明和表达式列表的嵌套名称说明符中表示的基类如下所述,并且其函数体中的复合语句为空 (12.6.2)。如果该用户编写的构造函数格式不正确,则程序格式不正确。表达式列表中的每个表达式都是static_cast<T&&>(p)
的形式,其中p
是相应构造函数参数的名称,T
是声明的p
类型。
因此,构造函数参数被完美地转发给相应的继承构造函数(std::forward
(§20.2.3)被指定返回static_cast<T&&>(p)
,与上面的描述完全相同)。根据构造函数参数的声明类型,引用折叠将按照本答案中所述发生。
在您的情况下,[T=string&&]
和强制转换再次产生string&&
,这可以绑定到B
的参数。若要在 E
中匹配该行为,应将构造函数重写为
E(string&& a) : B(static_cast<string&&>(a))
{
}
- 返回的指向C++对象的链接是什么样的
- 这些是什么样的错误?即使我不在 Linux 上工作,我也遇到了 Linux 错误
- Clang 工具,用于提取给定 lambda 类型的 lambda 主体
- 我可以在构造函数的主体中转发构造吗?
- C++:如何在声明枚举类的模板类主体之外定义枚举类?
- GCC 能否优化具有相同主体的函数的代码大小?
- 构造函数主体内的本地指针C++内存泄漏
- 如何在方法主体中返回声明向量的引用?
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取
- 我可以检查初始化列表中设置的构造函数主体中的变量吗
- 在陈述"Implementation-defined"时,什么样的软件是"Implementation"的一部分?究竟什么是"Implementation"?
- 如果函数是在类的主体中定义的,我是否需要在成员函数的返回类型中指定 typename?
- 重载运算符主体仅包含一个函数调用
- 虚幻引擎使用什么样的反射?
- boost::ifind_first 会引发什么样的异常?
- 具有相同主体的两个函数具有不同的名称
- 什么样的 GCC 优化可能会根据是否打印来更改双精度?
- 错误 C2084:函数"int main(void)"已具有主体
- C++ 没有在命名空间外部声明的类主体的类
- 继承的构造函数的定义(主体)是什么样的