在C ++ 11中,可以“继承构造函数”:
struct A{ };
struct B : A{
using A::A;
};
在某些情况下(参见下面的讨论),也可以使用多个继承构造函数。
struct D : A, B, C{
using A::A;
using B::B;
using C::C;
};
最后,还可以从参数包中的所有类型继承:
template<class... Ts>
struct D2 : Ts...{};
问题:是否可以一般性地继承基类的所有构造函数?像这样:
template<class... Ts>
struct D2 : Ts...{
using Ts::Ts...; // ??? compiler error
};
这样struct D2<A, B, C>
与上面的struct D
等效。
答案 0 :(得分:2)
通常(不太漂亮)的解决方法是递归:
template<class... Ts>
struct D { };
template<class T, class... Ts>
struct D<T, Ts...>: T, D<Ts...>{
using D<Ts...>::D;
using T::T;
};
请注意,在当前继承构造函数的规范下,这并不完全等同于
struct D : A, B, C{
using A::A;
using B::B;
using C::C;
};
版本,如果按值传递构造函数参数可能效率低,因为继承构造函数调用链需要多次移动(可能会退化为传统类型的副本)。 Demo。
论文N4429解决了这个以及与继承构造函数相关的其他一些问题,并已通过Lenexa的EWG审核。
答案 1 :(得分:0)
不,这样的事情是不可能的。有list of contexts允许发生包扩展, using-declaration 不是其中之一。
mem-initializer-list 是一个允许的上下文,所以你可以这样做:
struct A { A(int ) { } };
struct B { B(int ) { } };
template <typename... Ts >
struct D : Ts... {
template <typename... Args>
D(Args&&... args) : Ts(std::forward<Args>(args)...)... { }
};
int main() {
D<A, B> d(4);
}
上面实际上无法在gcc 5.2中编译(bug 65422)。