按值传递参考参数
Passing to a Reference Argument by Value
考虑这个简单的程序:
vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), foo.front(), 13);
for(const auto& i : foo) cout << i << 't';
当我写它时,我希望得到:
13 42 13 42 13 42
,但我得到了:
13 42 0 42 0 42
问题当然是replace
通过参考将最后两个参数列入最后两个参数。因此,如果它们中的任何一个碰巧在结果上运行的范围内可能是出乎意料的。i can 通过添加临时变量来解决此问题:
vector<int> foo = {0, 42, 0, 42, 0, 42};
const auto temp = foo.front();
replace(begin(foo), end(foo), temp, 13);
for(const auto& i : foo) cout << i << 't';
我确实知道C 11为我们提供了各种类型的工具,我可以简单地将该值强制为非参考类型并通过该内联,而无需创建临时?
解决方案可能如下(即使您是临时的)
template<class T>
void replace_value_of_first(std::vector<T>& v, const T& value)
{
std::replace(v.begin(), v.end(), T(v.front()), value);
}
您可以编写一个简单的函数,该功能接收参考并返回值。这将"将"引用"转换"为一个值。这确实产生了暂时的,但未命名,将在完整表达结束时被摧毁。像
template<typename T>
T value(const T& ref)
{
return ref;
}
然后您可以像
一样使用它int main()
{
vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), value(foo.front()), 13);
for(const auto& i : foo) cout << i << 't';
}
输出:
13 42 13 42 13 42
实时示例
您可以将给定值转换为rvalue
,以达到所需的效果。下面的示例有效,而无需定义任何额外的功能,只需将零添加到值中。
vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), foo.front()+0, 13);
for(const auto& i : foo) cout << i << 't';
甚至(如JAROD42所建议的)仅一级+
操作员,这是一个no-op:
vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), +foo.front(), 13);
for(const auto& i : foo) cout << i << 't';
显然,其中任何一个仍然创造暂时性。我认为您无法摆脱它。
in 此特定情况(当旧值是向量的第一个),您可以用 一般而言,我不知道是否有可能以一种简单的方式,而无需复制。 P.S。:对不起,我的英语不好。rbegin()
和rend()
换取替换顺序。int main ()
{
std::vector<int> foo = {0, 42, 0, 42, 0, 42};
std::replace(foo.rbegin(), foo.rend(), foo.front(), 13);
for(const auto & i : foo)
std::cout << i << 't';
std::cout << std::endl;
return 0;
}
要更明确,您可以使用 int()
作为构造函数来创建临时:
replace(begin(foo), end(foo), int(foo.front()), 13);
而不是添加值。请参阅演示。
一个应该适用于任何类型的衬里,不仅是数字:
replace(begin(foo), end(foo), make_pair(foo.front(),0).first, 13);
或不创建额外的字段:
replace(begin(foo), end(foo), get<0>( make_tuple(foo.front()) ), 13);
vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), static_cast<int>(foo.front()), 13);
assert(equal(begin(foo), end(foo), begin({13, 42, 13, 42, 13, 42})));
- Lambda闭包左值可以作为右值参考参数传递
- 遍历地图并将该对用作参考参数 C++11
- 什么是常量参考参数以及如何使用它?
- 函数参数绑定通过参考与传递指针传递数组的规则
- 参考类中的模板参数包
- 是否可以通过引用通过参数返回参考
- RVALUE参考与const lVALUE参考作为参数之间的混淆
- 可以将模板字段参考模板参数作为第一个模板参数传递
- 二进制搜索树插入带参数参考
- 将参考类型作为嵌套模板结构中的模板参数作为模板参数不起作用
- 如何将rvalue作为参考参数传递给函数
- 强制扣除模板参数要参考
- 移动 l 值参考参数是否是一种不好的做法?
- C 11:为什么RVALUE参考参数隐式转换为LVALUE
- 转发模板参数的const-度,我应该使用转发参考
- 参考变量参数与本地参考变量
- 无法将类对象转换为函数默认参数中的参考
- 为什么可以将其他类型变量用作C 中常量参考参数参数的参数
- 如何处理可能指向内部数据的参考参数
- 用于未使用参数参考的单线解决方案