C++以迭代器作为参数的成员函数
C++ member function with iterator as parameter
我想写一个类test
,它能够存储一个函数,该函数能够遍历由经典[first,last)
迭代器对标识的元素集合,即:
template <typename T>
struct sum
{
template <typename I>
T operator()(I first, I last) const
{
T res = 0;
while (first != last)
{
res += *first;
++first;
}
return res;
}
};
//...
int main()
{
test<double> t;
t.set(sum<double>);
double a[] {1.,2.,3.};
std::cout << "Test (array) => " << t.call(a, a+3) << std::endl;
std::vector<double> v {1.,2.,3.};
std::cout << "Test (vector) => " << t.call(v.begin(), v.end()) << std::endl;
std::list<double> l {1.,2.,3.};
std::cout << "Test (list) => " << t.call(l.begin(), l.end()) << std::endl;
}
我想使用 std::function
,但我未能做到这一点,因为我无法声明模板化的迭代器对。一个可能的解决方法如下,但是它仅适用于普通数组(例如,double[]
或 double*
,如上面的变量 a
),而不适用于其他容器(例如,如上述变量 v
和 l
):
template <typename T>
class test
{
public:
template <typename F>
void set(F f)
{
f_ = f;
}
template <typename I>
T call(I first, I last) const
{
return f_(first, last);
}
private:
std::function<T(T*,T*)> f_;
};
关于如何获得正确行为的任何想法?
注意:我正在使用GCC 4.9.2 --std=c ++ 11进行编译
谢谢。
你想要的是能够构造一个:
std::function<T(FwdIter<T>, FwdIter<T>)>
其中FwdIter<T>
是一些类型擦除的类,它满足了 ForwardIterator 概念并被取消引用到T
。为此,请查看Boost.TypeErasure库,我们可以在其中执行以下操作:
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/mpl/vector.hpp>
using namespace boost::type_erasure;
template <typename T>
using FwdIter = any<
boost::mpl::vector<
copy_constructible<>,
incrementable<>,
dereferenceable<T>,
equality_comparable<>
>>;
有了这个和你对sum
的定义,我可以做:
std::function<int(FwdIter<int>, FwdIter<int>)> f = sum<int>{};
std::vector<int> v = {1, 2, 3, 4, 5};
std::cout << f(v.begin(), v.end()) << std::endl; // prints 15
在您的test<T>
中,您可以根据需要拥有一个std::function<T(FwdIter<T>, FwdIter<T>)>
成员。
我试图研究另一种解决方案。
本质上,用户函数被包装在一个持有者持有者中,该持有者将函数签名固定为 T(const std::vector<T>&)
。关于@Barry的解决方案(我接受的解决方案),这不需要外部库。但是,由于在运行时构造矢量对象,它会遇到性能问题。此外,更重要的是,正如@Barry所指出的,该解决方案对T
施加了人为的要求(例如T
必须是可复制的)。
是这样的:
template <typename T,typename F>
class holder
{
public:
holder(F f) : f_(f) { }
T operator()(const std::vector<T>& v) const
{
return f_(v.begin(), v.end());
}
private:
F f_;
};
template <typename T>
class test_v2
{
public:
template <typename F>
void set(F f)
{
f_ = holder<T,F>(f);
}
template <typename I>
T call(I first, I last) const
{
return f_(std::vector<T>(first, last));
}
private:
std::function<T(const std::vector<T>&)> f_;
};
为什么不启动函子,如下所示:
template <typename T>
class test
{
public:
template <typename I>
auto call(I first, I last) const
-> decltype(T()(first, last))
{
return T()(first, last);
}
};
并使用它:
test<sum<double>> t;
现场示例
相关文章:
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法