C++:从模板化基类重写函数
C++: overriding function from templated base class
这是简单的版本。下面,我将全面解释现实世界的用例。
我有两个类:
template<class T>
class Base {
protected:
virtual void foo();
std::map<std::string*, T*> things;
};
class Derived : public Base<int> {
protected:
void foo();
};
template<class T>
void Base<T>::foo() {
for (auto itr = things.begin(); itr < things.end(); ++itr) {
}
}
void Derived::foo() {
for (auto itr = things.begin(); itr < things.end(); ++itr) {
}
}
我在foo
的Derived
实现中遇到了 for 循环条件的问题:
example.cpp: In member function ‘virtual void Derived::foo()’:
example.cpp:23:53: error: no match for ‘operator<’ in ‘itr < ((Derived*)this)->Derived::<anonymous>.Base<int>::things.std::map<_Key, _Tp, _Compare, _Alloc>::end<std::basic_string<char>*, int*, std::less<std::basic_string<char>*>, std::allocator<std::pair<std::basic_string<char>* const, int*> > >()’
example.cpp:23:53: note: candidates are:
In file included from /usr/include/c++/4.7/string:54:0,
from example.cpp:2:
/usr/include/c++/4.7/bits/basic_string.h:2590:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.7/bits/basic_string.h:2590:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: mismatched types ‘const _CharT*’ and ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’
In file included from /usr/include/c++/4.7/string:54:0,
from example.cpp:2:
/usr/include/c++/4.7/bits/basic_string.h:2578:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
/usr/include/c++/4.7/bits/basic_string.h:2578:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::basic_string<_CharT, _Traits, _Alloc>’
In file included from /usr/include/c++/4.7/string:54:0,
from example.cpp:2:
/usr/include/c++/4.7/bits/basic_string.h:2566:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.7/bits/basic_string.h:2566:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::basic_string<_CharT, _Traits, _Alloc>’
In file included from /usr/include/c++/4.7/map:62:0,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_multimap.h:822:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&)
/usr/include/c++/4.7/bits/stl_multimap.h:822:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::multimap<_Key, _Tp, _Compare, _Alloc>’
In file included from /usr/include/c++/4.7/map:61:0,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_map.h:906:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&)
/usr/include/c++/4.7/bits/stl_map.h:906:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::map<_Key, _Tp, _Compare, _Alloc>’
In file included from /usr/include/c++/4.7/map:60:0,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_tree.h:873:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator<(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
/usr/include/c++/4.7/bits/stl_tree.h:873:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>’
In file included from /usr/include/c++/4.7/bits/stl_algobase.h:68:0,
from /usr/include/c++/4.7/bits/stl_tree.h:63,
from /usr/include/c++/4.7/map:60,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_iterator.h:1063:5: note: template<class _Iterator> bool std::operator<(const std::move_iterator<_Iterator>&, const std::move_iterator<_Iterator>&)
/usr/include/c++/4.7/bits/stl_iterator.h:1063:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::move_iterator<_Iterator>’
In file included from /usr/include/c++/4.7/bits/stl_algobase.h:68:0,
from /usr/include/c++/4.7/bits/stl_tree.h:63,
from /usr/include/c++/4.7/map:60,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_iterator.h:1057:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::move_iterator<_Iterator>&, const std::move_iterator<_IteratorR>&)
/usr/include/c++/4.7/bits/stl_iterator.h:1057:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::move_iterator<_Iterator>’
In file included from /usr/include/c++/4.7/bits/stl_algobase.h:68:0,
from /usr/include/c++/4.7/bits/stl_tree.h:63,
from /usr/include/c++/4.7/map:60,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_iterator.h:349:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
/usr/include/c++/4.7/bits/stl_iterator.h:349:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::reverse_iterator<_Iterator>’
In file included from /usr/include/c++/4.7/bits/stl_algobase.h:68:0,
from /usr/include/c++/4.7/bits/stl_tree.h:63,
from /usr/include/c++/4.7/map:60,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_iterator.h:299:5: note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.7/bits/stl_iterator.h:299:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::reverse_iterator<_Iterator>’
In file included from /usr/include/c++/4.7/bits/stl_algobase.h:65:0,
from /usr/include/c++/4.7/bits/stl_tree.h:63,
from /usr/include/c++/4.7/map:60,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_pair.h:212:5: note: template<class _T1, class _T2> constexpr bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
/usr/include/c++/4.7/bits/stl_pair.h:212:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const std::pair<_T1, _T2>’
In file included from /usr/include/c++/4.7/bits/stl_algobase.h:68:0,
from /usr/include/c++/4.7/bits/stl_tree.h:63,
from /usr/include/c++/4.7/map:60,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_iterator.h:838:5: note: template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)
/usr/include/c++/4.7/bits/stl_iterator.h:838:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const __gnu_cxx::__normal_iterator<_Iterator, _Container>’
In file included from /usr/include/c++/4.7/bits/stl_algobase.h:68:0,
from /usr/include/c++/4.7/bits/stl_tree.h:63,
from /usr/include/c++/4.7/map:60,
from example.cpp:1:
/usr/include/c++/4.7/bits/stl_iterator.h:832:5: note: template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)
/usr/include/c++/4.7/bits/stl_iterator.h:832:5: note: template argument deduction/substitution failed:
example.cpp:23:53: note: ‘std::_Rb_tree_iterator<std::pair<std::basic_string<char>* const, int*> >’ is not derived from ‘const __gnu_cxx::__normal_iterator<_IteratorL, _Container>’
为什么这不起作用,我应该怎么做才能解决它?
PS:我知道这是使用模板专业化的绝佳机会,但我认为这不适合我的用例。
以下是完整的故事。
我正在制作一个包含多种节点的场景图。此问题的一些重要问题是:
- 场景父级
- 场景区域
- 场景组
- 场景组件
他们各自扮演以下角色:
-
SceneParent
包含一组模板类型 T 的子项。 -
SceneRegion
扩展SceneParent
,指定T作为SceneParent
-
SceneGroup
扩展SceneParent
,指定 T 作为SceneComponent
我尝试实现的功能是 getVisibleChildren
.给定一个视口,我想要接收一组应该渲染的SceneComponent
。
SceneParent
的实现是递归调用所有子项的:
template< class T >
void SceneParent< T >::getVisibleChildren(const util::Camera& camera,
std::vector< SceneComponent* >& visibleChildren) const {
if (!this->isVisible(camera)) {
return;
}
// Get ids into a flat container so the next loop can be parallelized.
std::vector< std::string* > childIds;
for (auto itr = this->children.cbegin(); itr < this->children.cend();
++itr) {
childIds.push_back(itr->first);
}
// TODO: parallelize this.
for (auto itr = childIds.cbegin(); itr < childIds.cend(); ++itr) {
this->children[*itr]->getVisibleChildren(camera, visibleChildren);
}
}
SceneGroup
的实现将其所有SceneComponent
添加到累加器中(假设如果一个组是可见的,那么它的组件也是可见的)。因此,SceneGroup
节点充当递归的基本情况:
void SceneGroup::getVisibleChildren(const util::Camera& camera,
std::vector< SceneComponent* >& visibleChildren) const {
if (!this->isVisible(camera)) {
return;
}
// If this group is visible, assume all of its components are as well.
for (auto itr = this->children.cbegin(); itr < this->children.cend();
++itr) {
visibleChildren.push_back(itr->second);
}
}
既然你已经在我的帖子中谈到了这一点,我假设你对我的真实世界应用程序感兴趣(至少是温和的),而不仅仅是它引起的编译器错误。因此,如果您愿意,请提供任何建议,说明我如何改进场景图的实现/我在从事此项目时应该注意的事情。
std::map<K, V>
的迭代器是双向迭代器。将小于运算符用于双向迭代器没有任何意义。只需使用相等或不相等运算符编写循环:
for (auto itr = things.begin(); itr != things.end(); ++itr) {
}
相关文章:
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 重写打印函数而不是覆盖基类
- 重写函数不打印基类数据
- 从基类调用重写的方法
- 我无法重写基类的方法,因为我的派生类是模板化的
- 哪个基类调用派生重写的方法?
- 如何在子类中重写时调用私有虚拟基类实现
- 在 c++ 中重写函数时如何选择基类?
- 基类能否知道派生类是否已重写虚拟方法
- 给定基类方法的编译时重写
- C ++中有没有办法让派生类重写基类静态方法
- 在派生类中重写哪个基类的虚拟析构函数
- 重写基类中的编译器宏
- 继承和重写 - 从基类调用重写子方法
- C++ - 如何使用基指针重写子类方法
- 重写模板基类中的纯虚拟函数
- 在继承时用指向派生类的指针重写指向基类的指针
- 调用重写函数并使用基类中的重载变量
- C++:从模板化基类重写函数
- 从基类重写虚方法