我正在使用c ++ 11功能,只是试验了以下代码:
void dump(ostream &os, const MyType &mt)
{
}
void f(const vector<MyType> &mts, ostream &os)
{
for_each(mts.begin(), mts.end(), bind(dump, ref(os), ref(_1));
}
此代码在clang编译错误:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algo.h:4417:2: error: no matching function for call to object of type
'std::_Bind<void (*(std::reference_wrapper<std::basic_ostream<char> >, std::reference_wrapper<const std::_Placeholder<1> >))(std::basic_ostream<char>
&, const MyType &)>'
__f(*__first);
如果我从ref
中删除_1
,则编译正常:
for_each(mts.begin(), mts.end(), bind(dump, ref(os), _1);
看起来像占位符没有参考,但只是想确认,你能列出语义定义为什么它没有?它实际上已经通过引用传递了吗?
答案 0 :(得分:6)
std::ref()
用于通过引用传递值,否则将作为副本传递。
在您的代码中,它用于传递os
,这是一个显然您不想复制的本地名称。
请记住,正是std::bind()
的调用才能复制。也就是说,std::bind()
返回的值包含每个传递对象的副本。 std::ref()
会阻止该副本并保留引用。
但占位符实际上不是std::bind()
返回的对象内的值。相反,它们是一个标记,指示函数将第n个参数转发给包装函数。这里的关键词是 forward :由于值被转发,如果你的函数需要引用,它将作为引用传递,如果你的函数需要副本,它将作为副本传递。
由于_1
不是要传递给函数的实际值,而是一个库技巧来指示应该从哪个值发出信号,因此使用std::ref()
毫无意义。< / p>