模板、通用容器和独特的 C++
我创建了一个通用容器,扩展了向量的功能...添加了常用函数的新功能。
但是,我有一个问题:删除重复的唯一项目。它包含更多步骤:排序、使项目唯一、擦除...新功能在于通过主 ID 对对象重新编号并重新计算一些哈希值。所以它不能在类 List 之外完成...
让我们想象一下通用容器的以下示例(简化):
template <typename Item>
class List
{
protected:
typename TList <Item>::Type items;
...
};
比较器已使用函子实现...
template <typename Item>
class isEqual
{
public:
bool operator() ( const Item &i1, const Item &i2 ) const
{
...
}
};
我们创建新列表并删除重复项:
List <Object> list;
list.rem_duplic(items.begin(), items.end(), isEqual <Object>);
如何实现函数 rem_duplicit有模板参数...如果List代表一个模板类,那么在声明list时必须指定函子的模板参数:
List <Object, Comparator <Type> > list;
并且它可以是限制性的:重复项只能通过一个条件删除,删除重复时不能设置函子items...这种构造是非法的:
template <typename Item>
class List
{
protected:
typename TList <Item>::Type items;
public:
template <typename Functor>
void rem_duplic(typename TList <Item>::Type ::iterator begin, typename TList <Item>::Type ::iterator end, Functor <Item>) ();
...
};
template <typename Item> template <typename Functor> //Illegal
void List<Item>::rem_duplic(typename TList <Item>::Type ::iterator begin, typename TList <Item>::Type ::iterator end, Functor <Item>)
{
}
我怎样才能合理地实现这样的功能,即我可以用模板化参数做什么
Functor <Item> ?
{}之间的内部功能我很清楚...
I have created a generic container extending capabilities of the vector... A new functionality for common functions from has been added.
However, I have one problem: removing duplicate unique items. It consists of more steps: sorting, making items unique, erase... The new functionality lies in the renumbering of objects by primary ID and recomputing of some hashes. So it can not be done outside the class List...
Let us imagine the following example of generic container (simplified):
template <typename Item>
class List
{
protected:
typename TList <Item>::Type items;
...
};
Comparatos have been implemented using functors...
template <typename Item>
class isEqual
{
public:
bool operator() ( const Item &i1, const Item &i2 ) const
{
...
}
};
We create new list and remove duplicate items:
List <Object> list;
list.rem_duplic(items.begin(), items.end(), isEqual <Object>);
How do I implement function rem_duplicit having template parameter... If List represents a template class so the template parameter of the functor must be specified when declaring list:
List <Object, Comparator <Type> > list;
And it can be restrictive: duplicate items can be removed only by one criterion, functor can not be set when removing duplicate items... This construction is illegal:
template <typename Item>
class List
{
protected:
typename TList <Item>::Type items;
public:
template <typename Functor>
void rem_duplic(typename TList <Item>::Type ::iterator begin, typename TList <Item>::Type ::iterator end, Functor <Item>) ();
...
};
template <typename Item> template <typename Functor> //Illegal
void List<Item>::rem_duplic(typename TList <Item>::Type ::iterator begin, typename TList <Item>::Type ::iterator end, Functor <Item>)
{
}
How can I reasonably implement such a function, i.e. what can I do with the templatized parameter
Functor <Item> ?
The internal functionality between {} is clear to me...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果要编写一个可以采用任意比较函数/函子作为参数的函数,请将该函数设置为通过比较器类型进行参数化的模板。例如:
因为最后一个参数是模板参数,所以调用者可以传入任何他们想要的类型,只要它可以用作比较器即可。
If you want to write a function that can take an arbitrary comparison function/functor as a parameter, make that function a template parameterized over the type of the comparator. For example:
Because the last argument is a template parameter, callers can pass in any type they want as long as it can be used as a comparator.
最后一个参数声明中的
是多余的。只是:(注意,您可以使用上面在声明中引入的 typedef 来缩短它)。该函数并不关心传递的参数是否是模板 - 它所需要做的就是使用参数(类型为 Item)调用它,编译器将正确替换。
事实上,有时函子是一个模板,而另一些时候它只是比较指定类型的函数。
两个注意事项:
请注意,可以声明模板采用另一个模板作为其参数,但您在这里不需要类似的东西。
The
<Item>
in last argument declaration is superfluous. Just:(note, that you can use the typedef you introduced above in the declaration to shorten it). The function does not care whether the passed argument is a template or not—all it needs to do is call it with the arguments (of type Item) and compiler will correctly substitute.
In fact, some times the functor will be a template and others it will be simply function comparing specified type.
Two notes:
Note, that it is possible to declare template taking another template as it's argument, but you don't need anything like that here.