为什么在使用 std::bind 时复制构造函数被调用两次?
Why is the copy ctor invoked twice when using std::bind?
我正在研究 std::function
和 std::bind
以了解如何复制参数以及是否可以保存一些复制操作。
我知道当使用 std::bind
时,参数是按值而不是引用传递的(除非指定了 std::ref
)。但是,当我 运行 下面的代码片段时,复制构造函数被调用了两次。有人可以解释为什么吗?
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
std::function 的这个构造函数的参数总是被复制,因此在 std::function.
http://en.cppreference.com/w/cpp/utility/functional/function/function
template< class F >
function( F f );
5) Initializes the target with a copy of f. If f is a null pointer to function or null pointer to member, *this will be empty after the call. This constructor does not participate in overload resolution unless f is Callable for argument types Args... and return type R. (since C++14)
我正在研究 std::function
和 std::bind
以了解如何复制参数以及是否可以保存一些复制操作。
我知道当使用 std::bind
时,参数是按值而不是引用传递的(除非指定了 std::ref
)。但是,当我 运行 下面的代码片段时,复制构造函数被调用了两次。有人可以解释为什么吗?
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
std::function 的这个构造函数的参数总是被复制,因此在 std::function.
http://en.cppreference.com/w/cpp/utility/functional/function/function
template< class F >
function( F f );
5) Initializes the target with a copy of f. If f is a null pointer to function or null pointer to member, *this will be empty after the call. This constructor does not participate in overload resolution unless f is Callable for argument types Args... and return type R. (since C++14)