Ita*_*iwa 3 c++ algorithm templates decltype c++11
Hello I am asked to simulate the algorithm std::copy_if in this example to copy the odd values into s list of integers and the even ones also int another list so here is my example:
#include <list>
#include <vector>
#include <iostream>
template <typename T>
bool is_odd_pred(T x) {
return x % 2 != 0;
}
template <typename T>
bool is_even_pred(T x) {
return !(x % 2);
}
template <class T, class U>
void cpy_if(T first, T last, U destIt, bool(*pfnPred)(decltype(*first + 1))) {
while (first != last) {
if (pfnPred(*first))
*destIt++ = *first;
++first;
}
}
int main() {
std::vector<int> v1{ 10, 27, 57, 77, 81, 24, 16, 23, 28 };
for (auto i : v1)
std::cout << i << ", ";
std::cout << std::endl;
std::list<int> li_odd;
//cpy_if(v1.cbegin(), v1.cend(), li.begin(),
// [](decltype(*v1.cbegin() + 1) a) { return (a % 2 != 0); });
cpy_if(v1.cbegin(), v1.cend(), std::back_inserter(li_odd), is_odd_pred);
for (auto i : li_odd)
std::cout << i << ", ";
std::cout << std::endl;
std::list<int> li_even;
cpy_if(v1.cbegin(), v1.cend(), std::back_inserter(li_even), is_even_pred);
for (auto i : li_even)
std::cout << i << ", ";
std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
The program looks to work fine but Is it that correct context to use decltype in my cpy_if algorithm? Because I only made the algorithm has two elements types which are considered to be iterators.? Thank you for any help, tips, suggestion.
明显的问题是*first + 1不适用于某些类型。
我认为您已经添加了它,以防止decltype给您提供参考。如果是这样,则更可靠的等效项是:
bool(*pfnPred)(std::remove_cv_t<std::remove_reference_t<decltype(*first)>>)
Run Code Online (Sandbox Code Playgroud)
从C ++ 20开始,它可以简化为:
bool(*pfnPred)(std::remove_cvref_t<decltype(*first)>)
Run Code Online (Sandbox Code Playgroud)
接下来,使用函数指针会对谓词施加不必要的限制。
它不允许您使用有状态的lambda或参数类型略有不同的函数(例如bool pred(const int &) {...})。
您可以使函数接受任意可调用对象,而不是使用函数指针。(这是标准算法的工作方式。)
template <class T, class U, class F>
void cpy_if(T first, T last, U destIt, F pfnPred) {
while (first != last) {
if (pfnPred(*first))
*destIt++ = *first;
++first;
}
}
Run Code Online (Sandbox Code Playgroud)
为了提高安全性,可以使用pfnPred(std::as_const(*first))防止谓词通过非const引用接受参数并对其进行修改。