如何轻松实现成员函数作为模板参数
How to easily implement member functions as template argument?
我想开发一个容器,它可以用其属性访问成员函数(如Name())对其元素进行排序。我想把它用作下面的
SortedVector<T, &T::Name> v;
T t;
v.Add(t);
v.FindElementWithName("AName");
如何声明模板类?非常感谢。
除非只允许一种函数结果类型,否则没有声明允许您设想的简单用法。
有了这个限制,你可以这样做:
template< class Item, std::string (Item::*)() const >
class SortedVector;
但更一般地(不支持简单符号),你可以做
template< class Item, class Result, Result (Item::*)() const >
class SortedVector;
主要的问题是如何利用标准库的类。
我想我会使用std::vector
进行存储,std::map
进行排序,也许。
下面的一些代码与您想要的非常相似:提供基于单个对象的"keygetter"而不是两个对象的比较器的排序。使用lambdas的c++ 11x版本应该相当干净(这是改编自一些旧的gcc 4.4代码)。
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <string>
#include <vector>
template <
typename T,
typename K
> struct sort_by_key_comparator {
sort_by_key_comparator(boost::function<K(const T&)> keygetter)
:_keygetter(keygetter){}
bool operator()(const T& a,const T& b) {
return (_keygetter(a)<_keygetter(b));
}
boost::function<K(T)> _keygetter;
};
// Sort an iterator range based on comparison of
// keys of type K retrieved from ojects of type T
template <
typename IT,
typename T,
typename K
> void sort_by_key(
IT first,
IT last,
boost::function<K(const T&)> keygetter
) {
sort_by_key_comparator<T,K> cmp(keygetter);
std::sort(first,last,cmp);
}
class data {
public:
data(int id,const std::string& txt)
:_id(id),_txt(txt){}
int get_id() const {return _id;}
const std::string& get_txt() const {return _txt;}
private:
int _id;
std::string _txt;
};
int main(int,char**) {
std::vector<data> v;
v.push_back(data(0,"d"));
v.push_back(data(3,"c"));
v.push_back(data(1,"b"));
v.push_back(data(2,"a"));
boost::function<int(const data&)> idkey=
boost::bind(&data::get_id,_1);
sort_by_key(v.begin(),v.end(),idkey);
for (size_t i=0;i<v.size();++i)
std::cout << v[i].get_id() << ", " << v[i].get_txt() << std::endl;
std::cout << std::endl;
boost::function<std::string(const data&)> txtkey=
boost::bind(&data::get_txt,_1);
sort_by_key(v.begin(),v.end(),txtkey);
for (size_t i=0;i<v.size();++i)
std::cout << v[i].get_id() << ", " << v[i].get_txt() << std::endl;
}
有趣的是,Python的排序使用这种"keygetter"风格,而c++的STL/std库当然是基于双对象比较器的。Scala帮助提供了这两种风格(通过sortBy
和sortWith
)。相关文章:
- 将可变参数函数的参数封装在类实例中
- QML 使用带有参数C++函数
- 使用可变参数函数作为模板参数
- 如何在C++中伪造虚拟可变参数函数模板?
- 为什么可变参数函数不适用于模板
- C++ std::functional 中的可变参数函数模板
- 可变参数函数指针的定义对于VxWorks spyLib来说不清楚
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 考虑引用和常量的可变参数函数包装器
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 在可变参数函数中转发特定范围的参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 使用带有一个参数函数的递归找到数字的平方
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 多个可变参数函数的单个模板参数包?
- 参数数据类型未知的可变参数函数
- 可变参数函数参数包扩展
- 使用模板可变参数函数将多个参数传递给另一个函数
- 对可变参数函数的递归调用的链接器错误
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类