派生自模板基类的模板构造函数
Derive from template constructor of template base class
只是好奇,是否有可能从模板类继承,并在派生类的构造函数中调用基类的构造函数,该基类也是模板化的,没有参数可以从中推导其类型?
template<typename T>
struct Base {
template<typename D>
Base() { // no argument of type D to infer from
static_assert(std::is_same<T,D>::value, "");
}
};
struct Derived : Base<int> {
Derived() : Base<int>::Base<int>() {} // is there a way to write it correctly?
};
在我的特定情况下,我可以用模板方法替换模板构造函数,但这仍然是一个关于语言灵活性的有趣问题。
C++标准对此有何规定(第14.8.1节):
[注意:由于显式模板参数列表跟随函数模板名称,并且由于转换成员函数模板和构造函数成员函数模板是在不使用函数名称的情况下调用的,因此无法为这些函数模板提供显式模板参数列表。--end Note]
这是一个注释,而不是一个规则,因为它实际上是另外两个规则的结果,一个在同一部分:
当引用函数模板专用化时,可以通过用模板参数列表限定函数模板名称来指定模板参数,方法与使用类模板专用化指定模板参数相同。
和12.1
构造函数没有名称。
构造函数模板的模板参数必须从它们的参数中推导出来,不能显式指定构造函数的模板参数。
因此,让Base
取一个伪参数来推导参数:
template <typename T>
struct dummy { }; // to prevent instantiation of T
template <typename T>
struct Base
{
template <typename D>
Base(dummy<D>)
{
static_assert(std::is_same<T, D>::value, "");
}
};
struct Derived : Base<int>
{
Derived() : Base<int>(dummy<int>{}) { }
};
通过这个问题的表述方式,它看起来像是一种荒谬的偏执狂。
想想普通类:
class Base
{
public:
Base() {}
};
class Derived: public Base
{
public:
Derived() //< default ctor
:Base //< this is the Base type
() //< this selects what ctor to call
{}
};
请注意,您调用:Base()
,它解析为Base::Base()
,而不是:Base::Base()
现在,通过临时化Base::Base()
,您实际上是在试图承认,对于Base可以有许多不同的默认ctor(使用()
)。这是对"默认"概念本身的无稽之谈。
即使Base本身不是一个模板,这也是不可能的:
class Base
{
public:
template<class T>
Base() {} //< are there infinite way to default construct Base ?!?
};
Base b; //< so how is b constructed ?
varadics只会让事情变得明显不同:
template<class T>
class Base
{
public:
template<class... S>
Base(S&&... s) { /* something to do */ }
};
class Derived: public Base<int>
{
public:
template<class... S>
Derived(S&&... s) //< Derived varadicly initialized
:Base //< base type ...
(std::forward<S>(s)...) //< ... to initialize with what
{}
};
请注意,在s
为空的情况下,您实际上是在从Derived()::Derived()
调用Base::Base()
,用<>
(无参数)临时化
相关文章:
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 参数包构造函数在类模板中隐藏用户定义的转换
- 具有已删除移动和复制构造函数的类的就地构造
- 创建一个没有复制构造函数的类的 std::vector 的 std::vector
- C++构造函数和类?
- 在 C++ 中,默认情况下构造函数为类的数据成员提供的值是多少?
- 如何在其他类中使用参数化构造函数制作类的对象?
- 具有值包装器的可变参数模板构造函数的类构造函数优先级
- 如何使用私有构造函数对类进行单元测试?
- C++虚拟函数:基类函数是调用的,而不是派生的
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- 从作为模板参数传递给构造函数的类继承,或者从它们继承
- 继承的构造函数忽略类内初始化
- 模板和隐式构造函数的类定义之外的友元声明
- 具有字符串文本构造函数的类不适用于 const 引用初始化
- 为什么具有私有构造函数的类不阻止从此类继承?如何控制哪些类可以从某个基继承?
- 具有多个非默认构造函数基的Singleton派生类
- 调用基默认构造函数模板类
- 当基类未指定构造函数时,如何使用仅具有带参数的构造函数的类派生基类?
- 构造所有基类不需要默认生成的构造函数