c++ - 为不同的容器定义一个函数
问题描述
我想定义一个接受不同类型容器的函数:拥有数据的容器(如std::vector
)和不拥有数据的容器(如boost::iterator_range
)。
我写了以下内容:
#include <vector>
#include <boost/range/iterator_range.hpp>
template<typename C>
void fill(C& c, typename C::value_type v){
for (auto& j : c)
j = v;
}
template<typename C> // How to avoid this implementation?
void fill(const C& c, typename C::value_type v){
for (auto& j : c)
j = v;
}
int main(){
std::vector<int> v(10);
auto rng = boost::make_iterator_range(v.begin(), v.end());
fill(v, 1); // Case 1 -- Calling on std::vector
fill(rng, 2); // Case 2 -- Calling on boost::iterator_range
// Case 3 -- Calling with an r-value, requires the overload
fill(boost::make_iterator_range(v.begin(), v.end()), 3);
// Case 4 -- Should not be allowed
// fill(std::vector<int>(10), 4);
}
我的第一个实现fill
效果很好,因为它接受了两种迭代器。
但是,由于boost::iterator_range
不拥有数据,它可以是const
(当数据是非常量时),所以我想允许右值作为参数。这意味着我需要第二个实现。
这是唯一的方法吗?有没有办法避免第二次实施?
解决方案
您可以使用完美转发:
template <typename C>
void fill(C&& c, typename std::decay_t<C>::value_type v) {
for (auto& j : c)
j = v;
}
这实际上并不是“完美转发”,因为您不希望利用移动语义,如果您愿意,您应该编写
std::forward<C>(c)
而不是c
¹
#include <boost/range/iterator_range.hpp>
#include <vector>
template <typename C>
void fill(C&& c, typename std::decay_t<C>::value_type v) {
for (auto& j : c)
j = v;
}
int main() {
std::vector<int> v(10);
auto rng = boost::make_iterator_range(v.begin(), v.end());
fill(v, 1); // Case 1 -- Calling on std::vector
fill(rng, 2); // Case 2 -- Calling on boost::iterator_range
// Case 3 -- Calling with an l-value, requires the overload
fill(boost::make_iterator_range(v.begin(), v.end()), 3);
}
¹ 请注意,如果您这样做,您必须小心不要在移动后使用。
推荐阅读
- javascript - React Hook useEffect 缺少与 useEffect 的依赖关系
- jwt - 修改自定义策略中的JwtIssuer ClaimsProvider,实现AD B2C中的JWE
- python - 通过切片重命名熊猫列,导致合并失败
- haskell - 限制 Sigma 中的类型
- powershell - 从 powershell 中的 get-childitem 命令创建指向文件夹搜索结果的符号链接,并以文件夹名称命名
- javascript - 使用 TypeScript 处理 Formik 提交
- java - java - 如何使用talend检查从ftp站点检索到的文件是否存在于java的本地文件夹中?
- php - 在 PHP 不工作的情况下修剪变量中的空间
- r - 如何删除R中文件名括号内的字符?
- python - 想要获取图像的一部分