我已经实现了unique_copy
的版本,但它确实有效。问题是我必须这样称呼它:
my_unique_copy(
in.begin(), // ok
in.end(), // ok
out.begin(), // ok
equals<Container::iterator> // <--sucks
);
我不喜欢的是等于函数equals<Container::iterator>
必须用Container::iterator
显式实例化。我认为可以从in.begin()
推断类型,类型为Container::iterator
。我试图在函数原型中将equals
声明为bool()(Iterator,Iterator)
,但它失败了。
../untitled2/main.cpp:20:32: error: 'parameter' declared as function returning a function
bool()(Iterator,Iterator) equals){
^
../untitled2/main.cpp:20:34: error: expected ')' before 'equals'
bool()(Iterator,Iterator) equals){
^
../untitled2/main.cpp:20:34: error: expected initializer before 'equals'
../untitled2/main.cpp: In function 'int main()':
../untitled2/main.cpp:41:79: error: 'my_unique_copy' was not declared in this scope
my_unique_copy(in.begin(),in.end(),out.begin(),equals<Container::iterator>);
^
这是代码:
template <typename Iterator>
bool equals(Iterator fst, Iterator snd){
return *fst==*snd;
}
bool myfunction (int i, int j) {
return (i==j);
}
template <typename Iterator, typename Comparator>
void my_unique_copy(Iterator begin,
Iterator end,
Iterator out_begin,
Comparator equals){
if (begin==end){
return;
}
*out_begin=*begin;
++begin;
while (begin!=end){
if (!equals(out_begin, begin)){
*(++out_begin)=*begin;
}
++begin;
}
}
int main(){
using Container = vector<int>;
Container in{1,2,2,3};
Container out(4);
my_unique_copy(in.begin(),in.end(),out.begin(),equals<Container::iterator>);
for_each(out.begin(), out.end(), [](int v){cout<<v<<" ";});
cout<<endl;
unique_copy(in.begin(),in.end(),out.begin(),myfunction);
for_each(out.begin(), out.end(), [](int v){cout<<v<<" ";});
}
这就是我想要的:
my_unique_copy(in.begin(), in.end(), out.begin(), equals);
答案 0 :(得分:2)
如果您将equals
实现为函子而不是函数模板,那么基本上可以得到您想要的内容:
struct equals {
template<typename Iterator>
bool operator ()(Iterator fst, Iterator snd) const {
return *fst == *snd;
}
};
// ...
my_unique_copy(in.begin(), in.end(), out.begin(), equals{});
请注意,因为标准库already has an equal_to
functor,您应该选择一个更好地表示您的仿函数与std::equal_to
之间差异的其他名称,例如iter_equals
。或者,更好的是,您应该使用 std::equal_to
而不是通过在调用equals
时取消引用迭代器来重新发明轮子,而不是传递迭代器本身(这就是标准库算法确实如此。