C ++ 11允许继承构造函数,从而可以避免大量的样板,尤其是类似于包装类的东西。 但是,似乎您已经可以使用可变参数模板实现此功能。

class B
{
public:
 B(int){//do something}
 B(int, char){//do something}
};

使用继承构造函数:

class D : public B
{
public:
 using B::B; 
};

使用可变参数模板并转发:

class D : public B
{
public:
 template <typename...Args>
 D(Args&&... args) : B(std::forward<Args>(args)...)
 {
 }
};

虽然一致性(对待构造函数和方法的相同方式using )和易用性很好的理由把继承构造成的语言,还有没有其他原因的第一个解决方案应首选第二? 我发现讨论继承构造函数的CWG文档( N1890N1898 )只是注意以下内容并继续:

仅仅是一个历史事故阻止使用它来为构造函数和普通成员函数工作。 如果构造函数被称为“ctor”或“构造函数”而不是被其类的名称引用,那么这将起作用。 我们建议将其作为继承构造函数的机制。

#1楼 票数:4 已采纳

最重要的原因是完美转发并不完美。 简单案例:

struct B {
    B(int* ) { .. }
};

现在考虑:

D d{0};

如果我们继承构造函数,这很好。 如果我们完美转发,我们将尝试构造B(int ) ,因为0推导为int ,这是一个不存在的构造函数。 失败!

其他故障情况包括支撑初始化,仅声明的静态const数据成员,重载函数和位域。

#2楼 票数:3

完美转发并不完美。 特别是,0作为实际参数减少为int而不是表示一般的nullvalue。 因此,对于构造函数采用指针参数, 0将作为继承构造函数的实际参数,但不用于转发。

我认为我曾经提到的另一个原因是,问题(我们真的需要继承构造函数)是否被播出,继承构造函数是一个简单的符号,用于概念上简单的事情,用于简单类的上下文中。 在C ++中有足够的强制复杂性和强制样板。

#3楼 票数:2

维护问题(编译器错误)可能会导致'使用'的偏好:

struct Base
{
    Base(int) {}
};

struct Derived : public Base
{
    using Base::Base;
};

struct DerivedTemplate : Base
{
    template <typename...Args>
    DerivedTemplate(Args&&... args)
    : Base(std::forward<Args>(args)...)
    {}
};

int main()
{
    // error: no matching function for call to ‘Derived::Derived(int, int)’
    Derived d(1, 2);

    // In instantiation of ‘DerivedTemplate::DerivedTemplate(Args&& ...) [with Args = {int, int}]’:
    // required from here
    // error: no matching function for call to ‘Base::Base(int, int)’
    DerivedTemplate dt(1, 2);
}

此外,每个模板实例化都是一个不同的构造函数(使用时不会相乘)

  ask by Pradhan translate from so

未解决问题?本站智能推荐:

1回复

从模板类继承并使用继承其构造函数

我想继承一个模板类,并使用“ using”来继承其构造函数。 但是当我调用move构造函数时,失败“没有匹配的构造函数” 构建结果
2回复

继承构造函数和虚拟基类

我即将创建一个异常类层次结构,概念上看起来像这样: 所有构造函数应该与ExceptionBase类的构造函数相同。 派生的异常仅在类型上有所不同,否则没有添加的功能。 上面代码中提到的最后一个异常类型也应该有这些构造函数。 这是否可以使用C ++ 11标准的继承构造函数功能? 如
2回复

继承构造函数只能部分工作

无论typedef是什么,我都有以下类,这样写,完全可以工作: 除了重载的typedef之外,我想创建一个实际上几乎相同的子类: 我想要实现的是创建一个B类,即: - 与A相同 - 具有所有As函数(A中有很少的成员函数,我没有写过) - 所有的As运算符 - 全部作为构造函数
2回复

继承的构造函数的定义(主体)是什么样的?

从我对SO和cppreference链接的答案的阅读中 继承的构造函数等效于用户定义的构造函数,该主体具有空主体,并且成员初始化程序列表由单个nested-name-specifier组成 ,后者将其所有参数转发给基类构造函数。 我得出的结论是,以下D类和E类应表现相同。
1回复

继承构造函数后查找基类名称

考虑以下代码: 凭直觉,很明显,这段代码是有效的,并且确实可以编译(用gcc和clang测试)。 但是,我想了解标准中的哪些内容使其有效。 具体而言,我想了解名称查找如何base在base foo()发现的基类,而不是继承的构造。 这是我对标准措辞的分析,表明应将其解析为构
1回复

默认情况下是继承构造函数noexcept(true)吗?

在这里我发现: 默认情况下,继承构造函数都是noexcept(true),除非它们需要调用noexcept(false)函数,在这种情况下这些函数是noexcept(false)。 这是否意味着在下面的示例中,继承的构造函数是noexcept(true) ,即使它已在基类中显式
1回复

使用boost :: multiprecision :: mpz_int构造函数继承失败

我试图创建一个派生自boost::multiprecision::mpz_int的类,并让它继承基类构造函数: #include <boost/multiprecision/gmp.hpp> using namespace boost::multiprecision; stru
1回复

noexcept,继承构造函数和无效使用实际完成的不完整类型

我不确定它是否是GCC编译器的错误或noexcept的预期行为。 请考虑以下示例: 如果删除noexcept ,则编译。 无论如何,正如在例子中,我从GCC v5.3.1得到了这个错误: 据我所知, struct D不是一个不完整的类型,但继承构造函数涉及到语句,看起来编