【发布时间】:2018-11-06 00:46:35
【问题描述】:
我正在使用std::function 和std::bind 来了解如何复制参数以及是否可以保存一些复制操作。
我了解当使用std::bind 时,参数是按值而不是引用传递的(除非指定了std::ref)。但是,当我运行以下 sn-p 时,复制构造函数被调用了两次。谁能解释一下原因?
struct token
{
static int i;
int code;
token()
: code(i++)
{
cout << __FUNCTION__ << ": " << code << endl;
}
virtual ~token()
{
cout << __FUNCTION__ << endl;
}
token (token const & other)
: code (other.code)
{
cout << "copy ctor: " << code << endl;
}
// update -- adding a move ctor
token (token const && other)
: code (std::move(other.code))
{
cout << "move ctor: " << code << endl;
}
// update -- end
void boo() const
{
cout << __FUNCTION__ << ": " << code << endl;
}
};
void call_boo(token const & t)
{
t.boo();
}
int main()
{
token t2;
cout << "default" << endl;
std::function< void () >(std::bind(&call_boo, t2));
cout << "ref" << endl;
std::function< void () >(std::bind(&call_boo, std::ref(t2)));
cout << "move" << endl;
std::function< void () >(std::bind(&call_boo, std::move(t2)));
cout << "end" << endl;
return 0;
}
运行时,会产生以下输出:
token: 1
default
// Without move ctor
// copy ctor: 1 // Makes sense. This is the passing by value.
// copy ctor: 1 // Why does this happen?
// With move ctor
copy ctor: 1
move ctor: 1
~token
~token
ref // No copies. Once again, makes sense.
move
// Without move ctor
// copy ctor: 1
// copy ctor: 1
// With move ctor
move ctor: 1
move ctor: 1
~token
~token
end
~token
【问题讨论】:
-
您是否考虑过using the
gdbdebugger 并设置断点来了解何时调用构造函数? -
我猜它首先被复制到活页夹函子中,然后后者被移动到
std::function对象中。但是由于您的token没有专用的移动构造函数,因此使用了复制构造函数。基本上,一切都如预期的那样。 -
现代有效 C++,第 34 条:优先使用 lambdas 而非 std::bind。
-
说真的,您自己的问题可以通过在调试器中放置一个断点并查看调用堆栈来回答。
标签: c++ std-function stdbind