使用 dectlype 推断模板元素类型中的数据类型是否正确?
Is it correct to use dectlype to deduce the data type in template's element type?
您好,我被要求模拟本例中std::copy_if
算法,将奇数值复制到整数的 slist
中,偶数值也复制到另一个列表中,所以这是我的例子:
#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;
}
该程序看起来工作正常,但是在我的cpy_if
算法中使用decltype
是正确的上下文吗?因为我只使算法具有两种元素类型,它们被认为是迭代器。? 感谢您的任何帮助,提示,建议。
明显的问题是*first + 1
不适用于某些类型。
我假设您添加了它以防止decltype
给您参考。如果是这样,更可靠的等价物是:
bool(*pfnPred)(std::remove_cv_t<std::remove_reference_t<decltype(*first)>>)
从C++20开始,可以缩短为:
bool(*pfnPred)(std::remove_cvref_t<decltype(*first)>)
接下来,使用函数指针会对谓词施加不必要的限制。
它不允许您使用有状态的 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;
}
}
为了提高安全性,可以使用pfnPred(std::as_const(*first))
来防止谓词通过非 const 引用接受参数并对其进行修改。
而不是decltype(*first)
或decltype(*first + 1)
它被认为更合适
typename iterator_traits<T>::value_type
您可以将谓词的类型作为模板参数,并利用函数模板参数推导。更多灵感(和可能的实现技巧(: https://en.cppreference.com/w/cpp/algorithm/copy
相关文章:
- 类对象在 c++ 中是否具有数据类型?
- C++中是否有用于长数据类型的 lower_bound() 函数?
- C++ - 检查结构数据类型中的单词是否为回文
- 即使基类和派生类只使用基元数据类型,我是否需要定义虚拟析构函数
- 是否可以用类似C/C++(或任何语言)的语言,从作为用户输入的字符串或文件中创建用户定义的数据类型
- boost odeint 中的受控误差步进器是否支持复杂的数据类型?
- 使用 dectlype 推断模板元素类型中的数据类型是否正确?
- 将分配的内存与基本数据类型一起使用时,是否需要新放置? std::complex?
- 是否可以使用 std::vector<std::any> vec;这将导致异构数据类型
- C++11 中是否有实际的 4 位整数数据类型
- 在 c++ 中确定某个值是否在该数据类型的最大范围内
- 是否有任何数据类型或方法可以计算当前单元格中先前数组单元格的总和
- 即使数据类型不同,是否有可能将帧的参数作为参数传递给回溯中的另一个帧
- 是否要确保一个线程修改的任何数据类型的共享变量对其他线程可见
- 如何检查程序是否超过数据类型存储
- 用于 str.find() 的size_t数据类型是否安全?
- 数据类型是否"int"定义为类?
- 将结构视为数据类型是否准确
- 使用小数据类型是否会减少内存使用(来自内存分配而不是效率)
- 如何检查数据类型是否为数组?(c++)