【发布时间】:2020-11-25 01:07:08
【问题描述】:
我想定义一个接受不同类型容器的函数:拥有数据的容器(如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);
}
我对@987654325@ 的第一个实现运行良好,因为它接受了两种迭代器。
但是,由于boost::iterator_range 不拥有数据,它可以是const(而数据是非常量),所以我想允许右值作为参数。这意味着我需要第二个实现。
这是唯一的方法吗?有没有办法避免第二次实现?
【问题讨论】:
-
如果你想允许右值作为输入,那么你应该有一个将右值引用作为参数的重载。在任何情况下,在显示的两个版本中,
v都应被视为 const 引用。 -
是的,我只是想知道是否有更好的方法来实现重载以避免代码重复。另外,据我了解,只有 const 参考实现不适用于 std::vector。
-
我说你应该传递
v参数,而不是c参数,因为v在所有情况下都是只读参数。 -
对不起,我误会了。我现在明白了,感谢您的评论,但这确实超出了我的问题的重点。
-
对于
c参数,由于它是模板化的,请查看"universal/forwarding references",它可以将左值或右值作为输入,具体取决于调用者。