如何用相同的参数从模板类继承到模板类
C++ How do I inherit from a template class, to a template class, with the same arguments
这个问题在这里已经有了答案除了,因为我读了上面的问题,仍然不知道哪里出了问题。编辑:不,它没有,这个错误的原因是不同的。
我正在尝试做这个:
template<typename T>
class base
{
protected:
base() {}
virtual ~base() {}
virtual void method(void* const voidp) const = 0;
};
template<typename T>
class child : public base<T> // ERROR: child is not a template type
{
public:
child(std::vector<T> arg)
: _arg{arg}
{
}
virtual ~child() {}
void method(void* const voidp) const
{
for(template std::vector<T>::const_iterator it = _arg.begin(); it != _arg.end(); ++ it)
{
method2(voidp, *it);
}
}
protected:
std::vector<T> _arg;
};
我有点困惑,因为这似乎是相同的链接的例子,除非我错了?
编辑:这是method2
void method2(void* const voidp, const double& arg) // second argument comes in both double and float formats
{
}
// so there is also a: void method2(void* const voidp, const float& arg)
不知道为什么你会看到
"//错误:child不是模板类型"
然而,一个明显的东西你错过了typename
在std::vector<T>::iterator it
应该是const_iterator
for(typename std::vector<T>::const_iterator it = _arg.begin();
it != _arg.end();
++it)
{
//method(voidp, *it); //<--- Assuming you've this somewhere not shown in current post
}
如果你和我有同样的问题,可能是你在代码的其他地方做了一个friend class
定义?在使用不同的编译器和编译器选项在不同的系统上摆弄我的代码后,我侥幸使其编译成功。我相信这是因为在某个时候我从项目的文件中删除了一行,当检查这个文件时,我认为它曾经在那里有一个友类定义。我假设这导致编译器认为我没有写模板类?虽然我不完全相信这就是原因。
这个错误可能没有原因,除非可能有一个没有类模板的预先声明的类child
。
一个原因可能是你应该使用()
而不是{}
来初始化成员:
child(std::vector<T> arg)
: _arg{arg}
{
}
应更正为:
child(std::vector<T> arg)
: _arg(arg)
{
}
最好通过const引用传递:
child(const std::vector<T>& arg)
: _arg(arg)
{
}
然而,还有其他一些东西可以改进以帮助程序:
for循环不能编译:
for(std::vector<T>::iterator it = _arg.begin(); it != _arg.end(); ++ it)
{
method2(voidp, *it);
}
T
是一个依赖名称,这意味着std::vector<T>::iterator
应该被更正为typename std::vector<T>::iterator
。你可以在这里阅读更多。
但是,std::vector<T>::iterator
也应该更正为std::vector<T>::const_iterator
。因为函数method
是const
,所以const
意味着函数将承诺不修改类的任何成员。然而,vector中的iterator begin()
函数不是const限定的,这意味着编译器不知道是否要修改成员。因此,必须使用重载const_iterator begin() const
,以便编译器显式地知道您不会修改任何成员。
c++11
,你可以使用range-for循环来使循环更短:
for(const auto& x : _arg)
{
method2(voidp, x);
}
不需要在类中声明两次public:
;一旦声明了一次public
,接下来的所有内容都将是公开的,直到编译器到达另一个protected
/private
关键字,其他关键字反之亦然。
注意class
的默认访问级别是private
, struct
的默认访问级别是public
。因此,您的类可以稍微修改如下:
template<typename T>
class child : public base<T>
{
public:
child(const std::vector<T>& arg)
: _arg(arg)
{
}
virtual ~child() {}
void method(const void* voidp) const
{
for(typename std::vector<T>::const_iterator it = _arg.begin(); it != _arg.end(); ++ it)
{
method2(voidp, *it);
}
}
protected:
std::vector<T> _arg;
};
同样适用于base
类:
template<typename T>
class base
{
protected:
base() {}
virtual ~base() {}
virtual void method(const void* voidp) const = 0;
};
与在函数声明中放置const
关键字的位置保持一致:
你有:void* const voidp
和const double& arg
。如图所示,const
关键字的位置不一致——一个在类型
为了一致性,最好使用:const void* voidp, const double& arg
或void* const voidp, double const& arg
。
最后,我使用MSVC编译了下面的代码,它工作得很好:
template<typename T>
class base
{
protected:
base() {}
virtual ~base() {}
virtual void method(const void* voidp) const = 0;
};
template<typename T>
class child : public base<T>
{
public:
child(const std::vector<T>& arg)
: _arg(arg)
{
}
virtual ~child() {}
void method(const void* voidp) const
{
for(typename std::vector<T>::const_iterator it = _arg.begin(); it != _arg.end(); ++it)
{
method2(voidp, *it);
}
}
protected:
std::vector<T> _arg;
};
希望这对你有帮助
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 如何用数字处理log(0)
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 如何用转义符替换字符串中的所有特殊字符
- 如何用参数值调用函数(仅在运行时已知)
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- 如何用RISC-V GD32VF103CBT6开发板卸载精确的ADC过采样
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 如何用模板继承类
- 如何用相同的参数从模板类继承到模板类