我正在将一些代码从 MSVC(没有 permissive-)移植到 linux,我了解到如果在类的初始化列表中调用模板基类的构造函数,则必须指定所有模板参数,否则会出现错误。似乎有点多余,因为如果您在重新输入模板参数时犯了一个错误,那就是一个硬错误:
错误:类型 'Base<int, true>' 不是 'Derived' 的直接或虚拟基数
完整代码在这里:
template <typename T, bool has_x>
struct Base
{
Base(T t): t_(t){
}
T t_=0;
};
template <typename T>
class Derived : public Base<T, false>
{
public:
// : Base<T, true> is hard error
Derived(const T& t) : Base<T, false>(t) {}
};
int main()
{
Derived d(47);
}
Run Code Online (Sandbox Code Playgroud)
这是否有充分的理由,或者只是标准化过程从未花时间处理这个用例的特殊情况?
您只需要在Derived模板时执行此操作,并且基的类型取决于其模板参数。
这编译,例如:
template <typename T>
class Derived : public Base<int, false>
{
public:
Derived(const T& t) : Base(t) {}
};
Run Code Online (Sandbox Code Playgroud)
据我所知,这里(在成员初始值设定项列表中)Base实际上是 的注入类名Base<...>,像其他所有东西一样从它继承而来。
如果基类的类型确实依赖于模板参数,则其继承的注入类名将变得不可访问(至少直接不可访问),就像从它继承的任何其他成员一样。
对于成员变量/函数,您需要添加this->来访问它,但对于类型成员,您需要Derived:::
template <typename T>
class Derived : public Base<T, false>
{
public:
Derived(const T& t) : Derived::Base(t) {}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
138 次 |
| 最近记录: |