如何在不重复函数的情况下推导出常量和非常量类型
How to deduce const and non-const type without duplicating functions?
假设我有这个函数:(它几乎对容器中的每个值运行一个函数,然后返回每次迭代结果的向量)
#include <vector>
using std::vector;
template<class F, class V>
auto vmap(const F &f, const V &v) -> vector<decltype(f(v[0]))> {
vector<decltype(f(v[0]))> result;
result.reserve(v.size());
for (auto &p : v)
result.push_back(f(p));
return result;
}
我不能这样称呼它:
vector<int> vint = {1,2,3,4,5};
vmap([](auto &p) {return p++;},vint);
因为参数vector
是const
,要实现它,我将不得不创建两个非const
V
vmap
和一个const
。
当有多个容器/vector
传递给一个函数时,它开始感觉太多,因为它让我编写2^containers_count
函数。
是否有任何(脏但有效)解决方案?
您可以使用转发引用绑定到两个普通的 l 值引用(例如 std::vector<int>&
) 和 r 值引用 ( std::vector<int>&&
)。
缺点是你永远无法按值传递(只有 ref、const ref 或 r-value ref),尽管我认为这对你来说不是问题:
template<class F, class V>
auto vmap(F&& f, V&& v) {
vector<decltype(f(v[0]))> result;
result.reserve(v.size());
for (auto& p : v)
result.push_back(f(p));
return result;
}
演示
请注意,如果您要传递常量容器(谢谢,Miles),您传递的 lambda 必须适用于两个 const,因此p++
是不可能的(尽管请注意一个模板实例化会修改输入,而另一个模板实例化不会,这可能是意想不到的):
vector<int> vint = {1,2,3,4,5};
vmap([](auto &p) {return p++;},vint);
const std::vector<int> vint2 = vint;
vmap([](auto &p) {return p+1;},vint2);
如果要
允许函数修改向量,请从函数的参数中删除const
。v
的恒定性将从给出的论证中推断出来。
您也不需要指定返回类型,它将从 return
语句中推导出来。
template<class F, class V>
auto vmap(const F &f, V &v) {
vector<decltype(f(v[0]))> result;
result.reserve(v.size());
for (auto&p : v)
result.push_back(f(p));
return result;
}
请注意,result.reserve(v.size());
仅适用于 std::vector
。如果你想推广你的算法,你需要删除该行,或者专门用于它。
您可以使用采用常量向量的 lambda。对于您的示例:
vmap([](const auto &p) {return p+1;}, vint);
或者修改vmap
,它不需要常量向量。对于您的示例:
auto vmap(const F &f, V &v)
相关文章:
- 是默认情况下分配给char数组常量的值
- 如何在 c++ stl 中获取列表中被推回的元素的地址,在常量时间内?
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 这种特殊情况下的外部常量
- 为什么在这种情况下调用非常量右值移动构造函数?
- 是否允许使用 VkBool32 作为推送常量?
- 如何在 C++03 中没有重复代码的情况下在堆栈上创建一个非常量 C 字符串数组?
- 矢量返回常量引用,不可能向下转换
- 如何在不初始化常量的情况下声明数组?
- 将矢量<int>推入矢量<矢量<int>>时,SIGABRT - free():下一个大小无效(快速)
- 下推解析器是否扫描令牌或单个字符
- 如何在不违反常量正确性的情况下使用 std::lock_guard
- 现代C++编译器是否能够避免在某些条件下两次调用常量函数
- 我可以在不推送向量的情况下向向量添加值吗?
- 如何在不重复函数的情况下推导出常量和非常量类型
- 我们可以在不使用构造函数的情况下推回包含矢量的结构
- 默认情况下,非常量变量不被视为外部变量吗?
- 错误推回对常量向量元素的引用
- 如何设计下推自动机
- 在编译时常量中对字符串文本进行下标