作爲後續,我來到這個解決方法:
template<class T>
struct mover
{
mover(T const& val) : val(val) {}
mover(T&& val) : val(std::move(val)) {}
mover(mover const& other) = default;
mover(mover&& other) = default;
mover(mover& other) : val(std::move(other.val)) {}
operator T const&() const
{
return val;
}
T val;
};
template<class T>
using wrap_t = typename std::conditional
<
std::is_move_constructible<T>::value
&& !std::is_trivially_copy_constructible<T>::value
, mover<T>
, T
>::type;
template<class... Ts>
auto pack_impl(wrap_t<Ts>... ts)
{
return [=](auto&& f)->decltype(auto)
{
return f(static_cast<Ts const&>(ts)...);
};
}
auto pack = [](auto&&... ts)
{
return pack_impl<std::decay_t<decltype(ts)>...>(static_cast<decltype(ts)>(ts)...);
};
它利用mover
作爲代理,它允許lambda通過移動捕獲它(這有點哈克)。 wrap_t
決定什麼時候需要或有益於應用mover
。
現在我們可以測試一下:
struct A
{
A() = default;
A(A&&)
{
std::cout << "move\n";
}
A(A const&)
{
std::cout << "copy\n";
}
};
A a;
std::cout <<"p1------------\n";
auto p1 = pack(std::move(a));
std::cout <<"p2------------\n";
auto p2 = std::move(p1);
std::cout <<"p3------------\n";
auto p3 = p2;
會打印:
p1------------
move
move
p2------------
move
p3------------
copy
你在捕獲'&'和使用'f(std :: move(t)...)時有什麼問題? – chris
@chris只要'pack'返回,引用就會變成懸浮的,不是? – Brian
@布萊恩,噢,好點。我沒有注意到它正在返回。 – chris